Skip to content

Cloudflare DNS records are updated in an infinite loop #5934

@jakjakmetmet

Description

@jakjakmetmet

What happened:
I have recently upgraded from 0.13.4 to 0.19.0 with an intermediate upgrade to 0.13.5(out of caution with regard to registry=txt changes, probably not necessary). Logs show that external-dns keeps updating dns records after its creation(A record and its TXT record). To note is that first all A records are "UPDATE"ed and then all TXT records in an infinite loop.

{"level":"debug","msg":"zoneIDFilter configured. only looking up zone IDs defined","time":"2025-10-31T17:08:20Z"}
{"level":"debug","msg":"looking up zone \"REDACTED\"","time":"2025-10-31T17:08:20Z"}
{"level":"debug","msg":"adding zone for consideration","time":"2025-10-31T17:08:20Z","zoneID":"REDACTED","zoneName":"REDACTED"}
{"level":"debug","msg":"nat64Source: collecting endpoints and processing NAT64 translation","time":"2025-10-31T17:08:21Z"}
{"level":"debug","msg":"dedupSource: collecting endpoints and removing duplicates","time":"2025-10-31T17:08:21Z"}
{"level":"debug","msg":"multiSource: collecting endpoints from 1 child sources and removing duplicates","time":"2025-10-31T17:08:21Z"}
{"level":"debug","msg":"Skipping endpoint REDACTED 1 IN A  REDACTED [{external-dns.alpha.kubernetes.io/cloudflare-proxied true}] because owner id does not match, found: \"\", required: \"REDACTED\"","time":"2025-10-31T17:08:21Z"}
{"level":"debug","msg":"Skipping endpoint REDACTED 1 IN A  REDACTED [{external-dns.alpha.kubernetes.io/cloudflare-proxied true}] because owner id does not match, found: \"\", required: \"REDACTED\"","time":"2025-10-31T17:08:21Z"}
{"level":"debug","msg":"Skipping endpoint REDACTED 1 IN A  REDACTED [{external-dns.alpha.kubernetes.io/cloudflare-proxied true}] because owner id does not match, found: \"\", required: \"REDACTED\"","time":"2025-10-31T17:08:21Z"}
{"level":"debug","msg":"Skipping endpoint REDACTED 1 IN A  REDACTED [{external-dns.alpha.kubernetes.io/cloudflare-proxied true}] because owner id does not match, found: \"\", required: \"REDACTED\"","time":"2025-10-31T17:08:21Z"}
{"level":"debug","msg":"zoneIDFilter configured. only looking up zone IDs defined","time":"2025-10-31T17:08:21Z"}
{"level":"debug","msg":"looking up zone \"REDACTED\"","time":"2025-10-31T17:08:21Z"}
{"level":"debug","msg":"adding zone for consideration","time":"2025-10-31T17:08:21Z","zoneID":"REDACTED","zoneName":"REDACTED"}
# All A records are updated
{"action":"UPDATE","level":"info","msg":"Changing record.","record":"REDACTED","time":"2025-10-31T16:53:50Z","ttl":1,"type":"A","zone":"REDACTED"}
# ...
# All TXT records are updated
{"action":"UPDATE","level":"info","msg":"Changing record.","record":"REDACTED","time":"2025-10-31T16:54:32Z","ttl":1,"type":"TXT","zone":"REDACTED"}
# ...
# repeat

What you expected to happen:
After a complete sync I would expect following log entry to repeat every --interval if no new source object is added:
"level":"info", "msg":"All records are already up to date"
This was the case for versions 0.13.4 and 0.13.5.

What I tried:
I also double checked:

  • It appears that the number of dnsendpoints matters here. For a test setup with only one dnsendpoint below config works and no infinite loop is observed.
  • With nearly 300 dnsendpoints an infinite loop is observed.

Could it be related to #5181?

Increasing default --interval from 1m to 10m without success. There was a silent period between sync intervals but it just keeps updating.

How to reproduce it (as minimally and precisely as possible):
Environment: kubernetes v1.33.5
External-DNS version: v0.19.0
Helm chart version: 1.19.0
DNS provider: Cloudflare
Source: crd DNSEndpoint, nothing else!

It is a single external-dns deployment, no other deployment exists.

Helm values:

logFormat: json
logLevel: debug
provider:
  name: cloudflare
sources:
  - crd
txtOwnerId: REDACTED
policy: sync
env:
  - name: CF_API_TOKEN
    valueFrom:
      secretKeyRef:
        name: cloudflare-api-token
        key: api_token
extraArgs:
    - "--zone-id-filter=REDACTED"
    - "--cloudflare-proxied"
    - "--cloudflare-dns-records-per-page=2000"
    - "--cloudflare-record-comment=\"REDACTED\"

All DNSEndpoint configs are like so:

apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
  name: a-record
spec:
  endpoints:
  - dnsName: <NAME>
    recordTTL: 180
    recordType: A
    targets:
    - <IP>
status:
  observedGeneration: 1

What in the end is deployed (kubectl get deployment external-dns -o yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
  namespace: external-dns
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/instance: external-dns
      app.kubernetes.io/name: external-dns
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app.kubernetes.io/instance: external-dns
        app.kubernetes.io/name: external-dns
    spec:
      containers:
      - args:
        - --log-level=debug
        - --log-format=json
        - --interval=1m
        - --source=crd
        - --policy=sync
        - --registry=txt
        - --txt-owner-id=REDACTED
        - --provider=cloudflare
        - --zone-id-filter=REDACTED
        - --cloudflare-proxied
        - --cloudflare-dns-records-per-page=2000
        - --cloudflare-record-comment=REDACTED
        image: external-dns/external-dns:v0.19.0

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