Skip to content

registry/txt: parent A/AAAA created without TXT ownership companion when registry name overflows 63 chars #6430

@polleuretan

Description

@polleuretan

What happened:

When the TXT registry name exceeds the 63-character DNS label limit, the error is logged and the execution proceeds. So the parent A/AAAA endpoint is pushed to the provider with no ownership TXT companion. Once the source disappears, there is nothing in the TXT registry to match, so the parent record becomes an orphan.

Trigger conditions is when the source FQDN's leftmost label fits in 63 chars, but <txt-prefix><recordType-prefix><leftmost-source-label> does not.

What you expected to happen:

When the registry TXT cannot be created, the parent record should not be applied either.

How to reproduce it (as minimally and precisely as possible):

Validated against external-dns v0.20.0, provider=aws, in a private Route53 zone, using a single Service object so no ingress controller or load balancer is needed. Process flags: --source=service --source=ingress --registry=txt --policy=sync --provider=aws --aws-zone-type=private.

  1. Apply this Service. The leftmost label is exactly 63 chars — passes the source-side check; the registry TXT name becomes a-<63chars> = 65 chars and fails.
apiVersion: v1
kind: Service
metadata:
  name: bug-repro-extdns-overflow
  namespace: default
  annotations:
    external-dns.alpha.kubernetes.io/hostname: bug-repro-extdns-overflow-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com
    external-dns.alpha.kubernetes.io/target: "192.0.2.1"
    external-dns.alpha.kubernetes.io/ttl: "60"
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80
  selector:
    app: nonexistent
  1. Wait one reconcile cycle. external-dns logs at ERROR severity:
level=error msg="label a-bug-repro-extdns-overflow-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa in a-bug-repro-extdns-overflow-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com is longer than 63 characters. Cannot create endpoint"
  1. Inspect the DNS provider. The parent A exists; no a- TXT companion exists.
$ aws route53 list-resource-record-sets --hosted-zone-id <ZONE_ID> \
    --query 'ResourceRecordSets[?contains(Name,`bug-repro`)]'
[
  {
    "Name": "bug-repro-extdns-overflow-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com.",
    "Type": "A",
    "TTL": 60,
    "ResourceRecords": [{"Value": "192.0.2.1"}]
  }
]
  1. Delete the Service. Wait one reconcile cycle.

  2. The A record remains in Route53 indefinitely; policy=sync cannot reap it because there is no TXT registry entry tying it back to the source. external-dns emits no further log lines about the record (the source is gone).

Anything else we need to know?:

Suggested fix

Environment:

  • External-DNS version (use external-dns --version): v0.20.0 (Helm chart external-dns-1.20.0). Code path identical on v0.21.0 and master.
  • DNS provider: AWS Route53 (private hosted zones).
  • Others:
    • Process flags (subset relevant to the bug):
      --provider=aws
      --registry=txt
      --source=ingress
      --source=service
      --policy=sync
      --aws-zone-type=private
      --log-level=warning
      
    • Kubernetes: EKS, kubernetes 1.32.

Checklist

  • I have searched existing issues and tried to find a fix myself
  • I am using the latest release,
    or have checked the staging image to confirm the bug is still reproducible
  • I have provided the actual process flags (not Helm values)
  • I have provided kubectl get <resource> -o yaml output including status
  • I have provided full external-dns debug logs
  • I have described what DNS records exist and what I expected

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions