auto plugin: backup files in the zones directory may shadow live zones — is this intended?
I ran into surprising behavior with the auto plugin and wanted to check
whether it's a bug or working as designed.
What I observed
With this Corefile:
. {
auto example.org {
directory /etc/coredns/zones (.*)\.zone {1}
reload 2s
}
}and these files:
/etc/coredns/zones/example.org.zone # serial 2026052800
/etc/coredns/zones/example.org.zone.bak-20260528 # serial 2026052700queries for example.org returned the older serial from the .bak-...
file. CoreDNS logged:
[INFO] plugin/file: Successfully reloaded zone "example.org." in
"/etc/coredns/zones/example.org.zone.bak-20260528" with 2026052700 SOA serialI'd expected (.*)\.zone to only match filenames ending in .zone.
What I think is happening (please verify)
Tracing through the code, my guess is:
plugin/auto/setup.gocompiles the user's REGEXP as-is, without anchoring.plugin/auto/walk.gousesre.FindStringSubmatchIndex(base), which finds the leftmost match anywhere in the filename — so(.*)\.zonematches bothexample.org.zoneandexample.org.zone.bak-20260528, both extracting originexample.org.- In
walk.go, when a second file matches an origin that's already loaded,z.SetFile(path)swaps the file pointer rather than warning. Whichever filefilepath.Walkvisits last in lexical order wins.
I'm not 100% sure I'm reading the flow right, especially around SetFile —
would appreciate a sanity check from someone who knows the plugin better.
If this is unintended
A couple of small things might help users who hit it:
- A
log.Warningwhen multiple files in the directory match the same origin would have saved me a lot of time — I only spotted the swap after greping the log for "Successfully reloaded zone". - A README note that REGEXP is matched unanchored (so e.g.
(.*)\.zonealso matches.zone.bak,.zone.disabled, etc.) would set the right expectation up front.
Happy to send a PR for either of those if it'd be useful — just wanted to confirm the diagnosis first.
Environment
CoreDNS 1.14.3, Go 1.25.10, Linux/amd64. Plugin combination in the stanza
is auto + a third-party rfc2136 plugin; I don't think the latter is
involved (the swap happens in the auto plugin's own log line) but mentioning
it in case it matters.
Source: coredns/coredns