external-dns icon indicating copy to clipboard operation
external-dns copied to clipboard

In `TXTRegistry`, silently overwritten ownership data can lead to unpredictable behavior when multiple TXT records exist

Open jeidsath-epic opened this issue 5 months ago • 5 comments
trafficstars

Bug Report: Multiple Valid TXT Records with Different Owners Are Silently Overwritten

Summary

When using TXTRegistry, if there are multiple valid TXT records for the same DNS name and record type (each with different owners), ExternalDNS silently overwrites ownership information in-memory. This can lead to unpredictable behavior, such as:

  • Incorrectly skipping updates or deletions.
  • Unauthorized updates (if the wrong TXT is picked).
  • A general mismatch between the desired and actual state of the DNS records.

How to Reproduce

  1. Create a DNS record (e.g., foo.example.com) with two TXT records:

    foo.example.com.  TXT "heritage=external-dns,external-dns/owner=team-a"
    foo.example.com.  TXT "heritage=external-dns,external-dns/owner=team-b"
    
  2. Run ExternalDNS with --txt-owner-id=team-a.

  3. Observe that it does not recognize itself as the owner if team-b's record is parsed last.

Problematic Code

This snippet from registry/txt.go causes the silent overwrite:

labelMap := map[endpoint.EndpointKey]endpoint.Labels{}
...
labelMap[key] = labels  // Overwrites earlier ownership data

Proposed Fix

Instead of overwriting, detect and log a conflict when multiple TXT records with different owners are found for the same key.

Suggested Replacement Code

existingLabels, exists := labelMap[key]
if exists {
    if existingLabels["owner"] != labels["owner"] {
        log.Warnf("Conflicting TXT record owners for %s: '%s' vs '%s'",
            key.DNSName, existingLabels["owner"], labels["owner"])
        // optionally, continue to skip, or choose based on config
    }
    // keep the first seen, or decide which to prefer based on policy
} else {
    labelMap[key] = labels
}

Optional Configurations

To make this behavior configurable, consider adding flags:

  • --fail-on-txt-conflict=true: hard fail if conflicts exist.
  • --prefer-owner=team-a: prefer this owner if multiple found.
  • --force-txt-takeover=true: always assume ownership despite TXT.

Why This Matters

We are seeing external-dns creating conflicting TXT records (maybe failed Zone transfers in some level of our DNS infrastructure). Once the conflicting record is created, ownership flip-flops until the bad record is cleaned up.

Environment

  • ExternalDNS version: v0.13.4

jeidsath-epic avatar May 23 '25 16:05 jeidsath-epic