-
-
Notifications
You must be signed in to change notification settings - Fork 4
Open
Labels
bugSomething isn't workingSomething isn't working
Milestone
Description
Note: I believe this issue does NOT affect the alpha-5 release as it is caused by code changes since alpha-5 in the Git main branch, specifically the new zone loader.
Given the following IXFR served by NSD:
example.test. 5 IN SOA ns1.example.test. mail.example.test. 2 60 60 3600 5 <- Start of IXFR for serial 2
example.test. 5 IN SOA ns1.example.test. mail.example.test. 1 60 60 3600 5 <- Start of deletions from serial 1
www A 169.254.1.1
example.test. 5 IN SOA ns1.example.test. mail.example.test. 2 60 60 3600 5 <- Start of addiitions in serial 2
www A 192.168.0.1
example.test. 5 IN SOA ns1.example.test. mail.example.test. 2 60 60 3600 5 <- End of IXFR for serial 2
Cascade incorrectly rejects the IXFR with:
| 2026-03-02T14:35:07.112263Z INFO refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}: cascaded::loader: Refreshing Name(example.test.)
| 2026-03-02T14:35:07.112284Z DEBUG refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}:refresh{zone=example.test addr=127.0.0.1:1055}: cascaded::loader::server: Refreshing Name(example.test.) from server 127.0.0.1:1055
| 2026-03-02T14:35:07.112298Z TRACE refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}:refresh{zone=example.test addr=127.0.0.1:1055}: cascaded::loader::server: Attempting an IXFR against 127.0.0.1:1055 for Name(example.test.)
| 2026-03-02T14:35:07.112335Z DEBUG refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}:refresh{zone=example.test addr=127.0.0.1:1055}:ixfr{zone=example.test addr=127.0.0.1:1055}: cascaded::loader::server: Attempting an IXFR against 127.0.0.1:1055 for Name(example.test.)
| 2026-03-02T14:35:07.112634Z TRACE refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}:refresh{zone=example.test addr=127.0.0.1:1055}:ixfr{zone=example.test addr=127.0.0.1:1055}: domain::net::client::dgram: Received 230 bytes of message
| 2026-03-02T14:35:07.112654Z TRACE refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}:refresh{zone=example.test addr=127.0.0.1:1055}:ixfr{zone=example.test addr=127.0.0.1:1055}: domain::net::client::dgram: Received message is accepted
| 2026-03-02T14:35:07.112686Z TRACE refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}:refresh{zone=example.test addr=127.0.0.1:1055}:ixfr{zone=example.test addr=127.0.0.1:1055}: domain::net::xfr::protocol::iterator: XFR record 0: Record { owner: ParsedName(example.test.), class: Class::IN, ttl: Ttl(5), data: ZoneRecordData::Soa(Soa { mname: ParsedName(ns1.example.test.), rname: ParsedName(mail.example.test.), serial: Serial(2), refresh: Ttl(60), retry: Ttl(60), expire: Ttl(3600), minimum: Ttl(5) }) }
| 2026-03-02T14:35:07.112710Z TRACE refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}:refresh{zone=example.test addr=127.0.0.1:1055}:ixfr{zone=example.test addr=127.0.0.1:1055}: domain::net::xfr::protocol::iterator: XFR record 1: Record { owner: ParsedName(example.test.), class: Class::IN, ttl: Ttl(5), data: ZoneRecordData::Soa(Soa { mname: ParsedName(ns1.example.test.), rname: ParsedName(mail.example.test.), serial: Serial(1), refresh: Ttl(60), retry: Ttl(60), expire: Ttl(3600), minimum: Ttl(5) }) }
| 2026-03-02T14:35:07.112728Z TRACE refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}:refresh{zone=example.test addr=127.0.0.1:1055}:ixfr{zone=example.test addr=127.0.0.1:1055}: domain::net::xfr::protocol::iterator: XFR record 2: Record { owner: ParsedName(www.example.test.), class: Class::IN, ttl: Ttl(5), data: ZoneRecordData::A(A { addr: 169.254.1.1 }) }
| 2026-03-02T14:35:07.112752Z TRACE refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}:refresh{zone=example.test addr=127.0.0.1:1055}:ixfr{zone=example.test addr=127.0.0.1:1055}: domain::net::xfr::protocol::iterator: XFR record 3: Record { owner: ParsedName(example.test.), class: Class::IN, ttl: Ttl(5), data: ZoneRecordData::Soa(Soa { mname: ParsedName(ns1.example.test.), rname: ParsedName(mail.example.test.), serial: Serial(2), refresh: Ttl(60), retry: Ttl(60), expire: Ttl(3600), minimum: Ttl(5) }) }
| 2026-03-02T14:35:07.112773Z TRACE refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}:refresh{zone=example.test addr=127.0.0.1:1055}:ixfr{zone=example.test addr=127.0.0.1:1055}: domain::net::xfr::protocol::iterator: XFR record 4: Record { owner: ParsedName(www.example.test.), class: Class::IN, ttl: Ttl(5), data: ZoneRecordData::A(A { addr: 192.168.0.1 }) }
| 2026-03-02T14:35:07.112784Z TRACE refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}:refresh{zone=example.test addr=127.0.0.1:1055}:ixfr{zone=example.test addr=127.0.0.1:1055}: domain::net::xfr::protocol::iterator: XFR record 5: Record { owner: ParsedName(example.test.), class: Class::IN, ttl: Ttl(5), data: ZoneRecordData::Soa(Soa { mname: ParsedName(ns1.example.test.), rname: ParsedName(mail.example.test.), serial: Serial(2), refresh: Ttl(60), retry: Ttl(60), expire: Ttl(3600), minimum: Ttl(5) }) }
| 2026-03-02T14:35:07.112821Z DEBUG refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}: cascaded::loader::refresh: Updating the scheduling of 'Name(example.test.)' from Some(Instant { tv_sec: 4148565, tv_nsec: 80942976 }) to Some(Instant { tv_sec: 4148565, tv_nsec: 382927134 })
| 2026-03-02T14:35:07.112859Z ERROR refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}: cascaded::loader: Could not load the zone: the IXFR failed: could not write the zone data: a patchset did not change the SOA record zone=example.test
| 2026-03-02T14:35:07.112869Z TRACE refresh{zone=example.test source=Server { addr: 127.0.0.1:1055, tsig_key: None }}: cascaded::zone::storage: Giving up on the ongoing load zone=example.test
This appears to be because of this code (from
Line 189 in 6a92108
| Some(Ok(ZoneUpdate::BeginBatchDelete(_))) => { |
Some(Ok(ZoneUpdate::BeginBatchDelete(_))) => {
// This is an IXFR.
let mut writer = builder.patch().unwrap();
process_ixfr(&mut writer, updates, metrics)?;
if !interpreter.is_finished() {
// Fail: UDP-based IXFR returned a partial IXFR
return Err(IxfrError::IncompleteResponse);
}The issue is that process_ixfr() expects to receive the initial SOA that begins the batch delete, but that was already consumed. Note that the consumed SOA is still available as the unnamed _ value of BeginBatchDelete(_), but is no longer available via updates.next().
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working