#8130·coredns

auto plugin: backup files in the zones directory may shadow live zones — is this intended?

Author: rsp2kCreated May 28, 2026Updated Sep 14, 2026

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:

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 2026052700

queries 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 serial

I'd expected (.*)\.zone to only match filenames ending in .zone.

What I think is happening (please verify)

Tracing through the code, my guess is:

  1. plugin/auto/setup.go compiles the user's REGEXP as-is, without anchoring.
  2. plugin/auto/walk.go uses re.FindStringSubmatchIndex(base), which finds the leftmost match anywhere in the filename — so (.*)\.zone matches both example.org.zone and example.org.zone.bak-20260528, both extracting origin example.org.
  3. 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 file filepath.Walk visits 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.Warning when 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. (.*)\.zone also 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.