rfc2136 provider can write MX records but cannot read them back (AXFR handler has no MX case)
What happened
The rfc2136 provider writes MX records correctly, but cannot list them back. Records() (which uses AXFR via List()) switches over the record type and has no MX case, so any MX in the zone is dropped before it reaches the plan:
// provider/rfc2136/rfc2136.go — Records()
switch rr.Header().Rrtype {
case dns.TypeCNAME: ...
case dns.TypeDNAME: ...
case dns.TypeA: ...
case dns.TypeAAAA: ...
case dns.TypeTXT: ...
case dns.TypeNS: ...
case dns.TypePTR: ...
default:
continue // Unhandled record type
}The write path is type-agnostic (AddRecord just formats <name> <ttl> <type> <target> and calls dns.NewRR), so --managed-record-types=MX with a CRD source does create the record and its ownership marker. It then becomes invisible to the next reconcile.
What you expected to happen
A record external-dns creates should be readable by external-dns, so it can be updated or deleted like any other managed record.
How to reproduce it
--provider=rfc2136 --source=crd --registry=txt --policy=sync --rfc2136-axfr --managed-record-types=A --managed-record-types=MX, with an MX in a DNSEndpoint at a non-apex name (apex names hit a separate issue, kubernetes-sigs/external-dns#6125, and are silently blocked before this point).
Create is logged and works:
Adding RR: mxprobe.oleole.ai 300 MX 1 smtp.google.com
Adding RR: mx-mxprobe.oleole.ai 0 TXT "heritage=external-dns,external-dns/owner=...,resource=crd/.../oleole-ai-workspace-verification"The record and its marker exist in the zone and resolve. Then remove the endpoint and reconcile: no Removing RR: is ever logged, and the MX plus its ownership TXT remain in the zone indefinitely. Same for a target change — the old value is not replaced.
Verified the write itself is fine by reading the zone directly:
mxprobe.oleole.ai | MX | smtp.google.com
mx-mxprobe.oleole.ai | TXT | "heritage=external-dns,external-dns/owner=...,resource=..."So the record is present, owned, and in the AXFR output — it is simply discarded by the default: continue arm.
Anything else we need to know?
Two related observations:
SupportedRecordTypeis a separate gate and not the cause here.provider/recordfilter.goexcludesMX, and neitherrfc2136norpdnsoverrides it, unlikeaws/azure/cloudflare/google. But the plan's own filter (IsManagedRecord) honours--managed-record-types, which is why the create works. Fixing the AXFR case is what makes the record manageable; whetherSupportedRecordTypealso needs MX is a separate question (see #6180).DNAMEis in theRecords()switch but not inSupportedRecordType, which suggests the two lists have drifted. May be worth reconciling both in one pass.
Environment
- External-DNS version:
v0.23.0(also present on currentmaster) - DNS provider:
rfc2136→ PowerDNS Authoritative 5.2 (gpgsql backend), TSIG,--rfc2136-axfrenabled - Registry:
txt(--txt-owner-idset) - Source:
crd(DNSEndpoint)
Source: kubernetes-sigs/external-dns