[GH-ISSUE #3429] SQLite journal replay does not preserve SOA serial increments across restart after dynamic updates #1180

Closed
opened 2026-03-16 01:49:20 +03:00 by kerem · 2 comments
Owner

Originally created by @zachsmith1 on GitHub (Jan 8, 2026).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/3429

Describe the bug
When using the SQLite journaling backend with dynamic updates enabled, Hickory increments the SOA serial in memory after a successful RFC2136 update, but that increment is not persisted. After restarting the server, the updated records are recovered from the journal, but the SOA serial reverts to the pre-update value.

To Reproduce
Steps to reproduce the behavior:

Using a simple zone and a SIG(0) update:

  1. Start hickory-dns with a sqlite-backed primary zone with allow_update = true and a journal.
  2. Query SOA serial: S1 = 2
  3. Send a dynamic update adding an A record (e.g. serialtest.example.com. A 192.0.2.55)
  4. Query SOA serial: S2 = 3 (so S2 = S1 + 1)
  5. Restart hickory-dns
  6. Query SOA serial again: S3 = 2 (S3 = S1, not S2) — even though the added A record is still present after restart.

Expected behavior
After a successful dynamic update that modifies zone contents, the SOA serial should remain monotonic across restarts. If the journal recovers the updated RRsets, it should also recover the updated SOA serial.

System:

  • OS: macOS
  • Architecture: aarch64
  • Version: 14.0
  • rustc version: 1.83.0

Version:
Crate: server
Version: main/0.26.0-alpha.1

Additional context
SqliteZoneHandler::update_records() journals the client-supplied update records (journal.insert_records(serial, records)) but the subsequent SOA serial bump (in_memory.increment_soa_serial()) is not appended to the journal. Recovery replays with auto_signing_and_increment = false, so the serial bump is not reconstructed.

crates/server/src/store/sqlite/mod.rs (update_records, recover_with_journal, journaling)
crates/server/src/store/sqlite/persistence.rs

Why this matters
Authoritative zone serials are used by secondaries and tooling; reverting serial across restart while serving updated zone data breaks expectations and can cause incorrect behavior for consumers relying on SOA serial monotonicity.

Originally created by @zachsmith1 on GitHub (Jan 8, 2026). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/3429 **Describe the bug** When using the SQLite journaling backend with dynamic updates enabled, Hickory increments the SOA serial in memory after a successful RFC2136 update, but that increment is not persisted. After restarting the server, the updated records are recovered from the journal, but the SOA serial reverts to the pre-update value. **To Reproduce** Steps to reproduce the behavior: Using a simple zone and a SIG(0) update: 1. Start hickory-dns with a sqlite-backed primary zone with allow_update = true and a journal. 2. Query SOA serial: S1 = 2 3. Send a dynamic update adding an A record (e.g. serialtest.example.com. A 192.0.2.55) 4. Query SOA serial: S2 = 3 (so S2 = S1 + 1) 5. Restart hickory-dns 6. Query SOA serial again: S3 = 2 (S3 = S1, not S2) — even though the added A record is still present after restart. **Expected behavior** After a successful dynamic update that modifies zone contents, the SOA serial should remain monotonic across restarts. If the journal recovers the updated RRsets, it should also recover the updated SOA serial. **System:** - OS: macOS - Architecture: aarch64 - Version: 14.0 - rustc version: 1.83.0 **Version:** Crate: server Version: main/0.26.0-alpha.1 **Additional context** `SqliteZoneHandler::update_records()` journals the client-supplied update records (`journal.insert_records(serial, records)`) but the subsequent SOA serial bump (`in_memory.increment_soa_serial()`) is not appended to the journal. Recovery replays with `auto_signing_and_increment = false`, so the serial bump is not reconstructed. [crates/server/src/store/sqlite/mod.rs](https://github.com/hickory-dns/hickory-dns/blob/7c91d6248b858174408f7e05692e5b6600f2c66e/crates/server/src/store/sqlite/mod.rs) (update_records, recover_with_journal, journaling) [crates/server/src/store/sqlite/persistence.rs](https://github.com/hickory-dns/hickory-dns/blob/7c91d6248b858174408f7e05692e5b6600f2c66e/crates/server/src/store/sqlite/persistence.rs) **Why this matters** Authoritative zone serials are used by secondaries and tooling; reverting serial across restart while serving updated zone data breaks expectations and can cause incorrect behavior for consumers relying on SOA serial monotonicity.
kerem closed this issue 2026-03-16 01:49:25 +03:00
Author
Owner

@cpu commented on GitHub (Jan 9, 2026):

Happy to review a PR with a fix if you're interested

<!-- gh-comment-id:3729557274 --> @cpu commented on GitHub (Jan 9, 2026): Happy to review a PR with a fix if you're interested
Author
Owner

@zachsmith1 commented on GitHub (Jan 14, 2026):

@cpu just gave it a shot. please share any/all feedback as I'm pretty new to rust

<!-- gh-comment-id:3747200068 --> @zachsmith1 commented on GitHub (Jan 14, 2026): @cpu just gave it a shot. please share any/all feedback as I'm pretty new to rust
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hickory-dns#1180
No description provided.