Hello!
I'm testing periodic key rollovers in a playground running Knot DNS 3.5.4 (I am
aware that 3.5.5 is out, but this message is also in the current source code)
Zone transfers are not being performed, neither incoming nor outgoing (the
latter occasionally to see zone content as shown below).
At the completion of each signing operation (with purposely very short
timings), I see the following debug output:
2026-06-19T08:39:32+0000 info: [b.net.] DNSSEC, signing zone
2026-06-19T08:39:32+0000 info: [b.net.] DNSSEC, KSK rollover started
2026-06-19T08:39:32+0000 info: [b.net.] DNSSEC, next key action, KSK tag 18749, submit at 2026-06-19T08:40:42+0000
2026-06-19T08:39:32+0000 info: [b.net.] DNSSEC, key, tag 15175, algorithm ECDSAP256SHA256, KSK
2026-06-19T08:39:32+0000 info: [b.net.] DNSSEC, key, tag 14234, algorithm ECDSAP256SHA256, public, active
2026-06-19T08:39:32+0000 info: [b.net.] DNSSEC, key, tag 60870, algorithm ECDSAP256SHA256, KSK, public, active
2026-06-19T08:39:32+0000 info: [b.net.] DNSSEC, key, tag 18749, algorithm ECDSAP256SHA256, KSK, public, active+ 2026-06-19T08:39:32+0000 info: [b.net.] DNSSEC, signing started
2026-06-19T08:39:32+0000 info: [b.net.] DNSSEC, successfully signed, serial 94, new RRSIGs 3
2026-06-19T08:39:32+0000 info: [b.net.] DNSSEC, next signing at 2026-06-19T08:40:42+0000
2026-06-19T08:39:32+0000 info: [b.net.] zone file updated, serial 93 -> 94
2026-06-19T08:39:32+0000 debug: [b.net.] disposal of old contents blocked by outstanding zone transfer
2026-06-19T08:40:42+0000 info: [b.net.] DNSSEC, signing zone
2026-06-19T08:40:42+0000 notice: [b.net.] DNSSEC, KSK submission, waiting for confirmation
2026-06-19T08:40:42+0000 info: [b.net.] DNSSEC, key, tag 15175, algorithm ECDSAP256SHA256, KSK
2026-06-19T08:40:42+0000 info: [b.net.] DNSSEC, key, tag 14234, algorithm ECDSAP256SHA256, public, active
2026-06-19T08:40:42+0000 info: [b.net.] DNSSEC, key, tag 60870, algorithm ECDSAP256SHA256, KSK, public, active
2026-06-19T08:40:42+0000 info: [b.net.] DNSSEC, key, tag 18749, algorithm ECDSAP256SHA256, KSK, public, ready, active+
2026-06-19T08:40:42+0000 info: [b.net.] DNSSEC, signing started
2026-06-19T08:40:42+0000 info: [b.net.] DNSSEC, successfully signed, serial 95, new RRSIGs 6
2026-06-19T08:40:42+0000 info: [b.net.] DNSSEC, next signing at 2026-07-03T06:45:11+0000
2026-06-19T08:40:42+0000 info: [b.net.] zone file updated, serial 94 -> 95
2026-06-19T08:40:42+0000 debug: [b.net.] disposal of old contents blocked by outstanding zone transfer
2026-06-19T08:40:42+0000 info: [b.net.] DS check, outgoing, remote 127.0.0.2@53 TCP, key p01., KSK submission check: negative
2026-06-19T08:40:52+0000 info: [b.net.] DS push, outgoing, remote 127.0.0.2@53 TCP, key p01., success
2026-06-19T08:41:42+0000 info: [b.net.] DS check, outgoing, remote 127.0.0.2@53 TCP, key p01., KSK submission check: positive
2026-06-19T08:41:42+0000 notice: [b.net.] DNSSEC, KSK submission, confirmed
The zone itself is trivially short:
$ dig -p 5340 @127.0.0.1 b.net AXFR +noall +answer +onesoa | ldns-read-zone -s
b.net. 60 IN SOA ns.b.net. root.b.net. 100 10800 3600 604800 3600
www.b.net. 60 IN HTTPS 0 b.net.
ns.b.net. 60 IN AAAA 2001:db8:2::4444
ns.b.net. 60 IN A 192.0.2.42
b.net. 60 IN NSEC3PARAM 1 0 0 -
b.net. 60 IN DNSKEY 257 3 13 zmXFV/KHpRk/E6l7oiRg2f2M+YpWxGqHFJtHmsAFl4KAxZPeiL2VIFLswpGnrwxO47//vz/I1VqsLhmUz9k35A== ;{id = 18749 (ksk), size = 256b}
b.net. 60 IN DNSKEY 256 3 13 x9PPypMDeXRarFtYwxT5uvQjE/DHQd6g+NcF5FkVGDhz/+Xq2r3ZDfLXYUjW1ivoZHstnH5hSC4znp9oghlLfw== ;{id = 38612 (zsk), size = 256b}
b.net. 60 IN TXT "DNS is innocent"
b.net. 60 IN NS ns.b.net.
and the IMO relevant bits of the configuration are:
acl:
- id: all_xfr
address: [ 127.0.0.1 ]
action: [ transfer, notify ]
submission:
- id: pdns_submission
check-interval: 60s
parent: pdns_remote
parent-delay: 10s
template:
- id: default
storage: "/tmp/zones"
zonefile-load: difference
file: "%s"
policy:
- id: autoFAST
keystore: pemstore
single-type-signing: off
manual: off
algorithm: ecdsap256sha256
ksk-shared: off
ksk-lifetime: 1h
zsk-lifetime: 2h
delete-delay: 1h
propagation-delay: 10s
nsec3: on
nsec3-iterations: 0
nsec3-salt-length: 0
nsec3-salt-lifetime: 0
cds-cdnskey-publish: rollover
zone-max-ttl: 60s
ksk-submission: pdns_submission
ds-push: pdns_remote
zone:
- domain: b.net
dnssec-signing: on
dnssec-policy: autoFAST
acl: [ all_xfr ]
Ought I be worried about "disposal of old contents blocked by outstanding zone
transfer"? I don't think I've noticed that before.
A second zone which uses the same policy shows the same behaviour.
Best regards,
-JP
Hello,
I would like to report a bug in Knot DNS 3.5.x where AXFR responses do not
have the Authoritative Answer (AA) bit set, which appears to violate RFC
5936 §2.2.
Affected versions tested:
- 3.5.3
- 3.5.4
Packages tested:
- cznic.1~bookworm
Summary
RFC 5936 §2.2 states:
"Each DNS message returned by the AXFR server MUST have the AA bit set to
1."
However, Knot DNS sends AXFR responses with flags set to qr only. The AA
bit is not set in any of the messages in the transfer stream.
As a result, strict secondary DNS servers, notably Windows Server DNS,
reject such responses as invalid and abort the zone transfer.
Expected behavior
AXFR response messages should have the AA bit set.
Expected flags:
qr aa
Actual behavior
AXFR response messages have only the QR bit set.
Actual flags:
qr
Possible root cause
The function axfr_process_query() in src/knot/nameserver/axfr.c does not
appear to call knot_wire_set_aa().
By contrast, the normal query path, via solve_answer() in internet.c, does
set the AA bit, so SOA, A, and other authoritative responses are returned
correctly. The AXFR code path appears to bypass this logic.
Minimal reproducer
dig @<knot-master> +tcp AXFR <zone> | head -2
Observed output:
;; flags: qr;
The AA bit is missing.
This can also be verified with tcpdump: byte 3 of each DNS message in the
AXFR stream has value 0x80 / QR only, instead of 0x84 / QR + AA.
--
Best regards,
Mateusz Masłowski
Hi all
I am having trouble forwarding a subdomain since I upgraded to the latest
knot.
For a couple of years I have been running a custom DNS server under
dynamic.estada.ch that the clients find via my regular infrastructure.
On my primary zone I have these records, but knot appears to answer weirdly:
*estada.ch.zone*
dynamic.estada.ch. 3600 A 185.194.239.135
dynamic.estada.ch. 3600 AAAA 2a0a:51c0::12b
dynamic.estada.ch. 3600 NS dynamic.estada.ch.
kdig AAAA dynamic.estada.ch @ns1.estada.ch
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 29173
;; Flags: qr rd; QUERY: 1; ANSWER: 0; AUTHORITY: 1; ADDITIONAL: 3
;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR
;; QUESTION SECTION:
;; dynamic.estada.ch. IN AAAA
;; AUTHORITY SECTION:
dynamic.estada.ch. 3600 IN NS dynamic.estada.ch.
;; ADDITIONAL SECTION:
dynamic.estada.ch. 3600 IN A 185.194.239.135
dynamic.estada.ch. 3600 IN AAAA 2a0a:51c0::12b
But public servers don't get the glue records:
kdig AAAA dynamic.estada.ch @9.9.9.9
;; ->>HEADER<<- opcode: QUERY; status: SERVFAIL; id: 63899
;; Flags: qr rd ra; QUERY: 1; ANSWER: 0; AUTHORITY: 0; ADDITIONAL: 1
;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR
;; QUESTION SECTION:
;; dynamic.estada.ch. IN AAAA
The trouble is that most resolvers are now unable to resolve the domain as
the AAAA and A queries still get answered with NS + additional A+AAAA.
Is there a configuration option to tell knot to actually respond with the A
or AAAA record when asked?
Also ANY, TXT, or CAA queries behave the same as NS queries:
kdig ANY dynamic.estada.ch @ns1.estada.ch
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 14419
;; Flags: qr rd; QUERY: 1; ANSWER: 0; AUTHORITY: 1; ADDITIONAL: 3
;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR
;; QUESTION SECTION:
;; dynamic.estada.ch. IN ANY
;; AUTHORITY SECTION:
dynamic.estada.ch. 3600 IN NS dynamic.estada.ch.
;; ADDITIONAL SECTION:
dynamic.estada.ch. 3600 IN A 185.194.239.135
dynamic.estada.ch. 3600 IN AAAA 2a0a:51c0::12b
I am happy for any pointers you may have.
Cheers,
Stefan