Zone fails to load permanently when a skeleton zone file is written over an existing journal #19
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
A zone fails to load permanently when the operator writes a fresh skeleton zone file at serial 1 over a zone whose existing journal (
.jnl) is still on disk at a higher serial. BIND refuses the inconsistent file/journal pair:Observed in production on
bind-externaldns-0:db.k8s.syd1.au.unkin.netrewritten to 249 bytes at serial 1, whiledb.k8s.syd1.au.unkin.net.jnl(7777 bytes, dated Aug 30, serial ~16) remained on the PVC.db.200.18.198.in-addr.arpabroke identically, so this affects the forward and reverse paths alike.The failure is persistent and self-reinforcing:
addzoneevery reconcile and rewrites the skeleton each time, so it never converges.BindZone k8s-syd1-au-unkin-netsat in phaseError/AddZoneFailed.Blast radius
The
bind-externaldnsService round-robins three pods, so roughly 1 in 3 authoritative answers became SERVFAIL.bind-resolverscached those failures and resolution for the wholek8s.syd1.au.unkin.netzone collapsed estate-wide — measured 0/20 success via resolver198.18.200.7, against 30/30 for a control name outside the zone.The visible symptom was not a DNS alarm. Gitea could not resolve
ci.k8s.syd1.au.unkin.net, so webhook deliveries to Woodpecker failed silently — no pipeline, no commit status, no log line. Three pushes/PRs acrossterraform-artifactapi,encapicandjellyfin-plugin-ssowere dropped and did not replay. It presented as "CI intermittently stopped firing".Remediation applied
Deleting the two stale
.jnlfiles was sufficient; the operator's next reconcile ranaddzonesuccessfully and both zones returned toReady. A subsequent pod restart came back clean, confirming the file/journal pair is consistent again.Proposal
Make zone-file writes safe when a journal already exists. Decide the mechanism against the real code — candidates:
.jnlwhenever the zone file is rewritten; a journal is only valid against the file it was derived from.out of rangeload failure and self-heal rather than retrying the same write.Requirements:
in-addr.arpazones are both covered.Acceptance
Ready.Related
Separate bug found during the same investigation, worth its own issue: the zone's
ns1glue is wrong. It currently servesA 10.42.2.159, a dead pod IP, and the skeleton writes the replica's own pod IP; it should be the LB VIP198.18.200.8. Masked today only becausebind-resolversuses a forward zone.unkin-agent referenced this issue2026-09-19 22:33:57 +10:00