TTR Networks

Intermediate · PowerDNS on Debian: authoritative, secondary, DNSSEC and recursor · section 9 of 10

Troubleshooting

✓ Lab-tested 21 October 2026 on Debian 13.7, PowerDNS Authoritative 4.9.17, PowerDNS Recursor 5.2.13, BIND dig 9.20.29

Most DNS problems are one of three things: the answer is old (a cache), the answer is refused (a policy), or the answer fails validation (DNSSEC). Modern servers usually say which, in an Extended DNS Error (EDE) next to the response code, so read the full dig output before guessing.

A broken chain of trust

The most dangerous DNSSEC mistake is a wrong DS at the parent, typically after changing a zone's key without updating the registrar. In the lab, a DS that doesn't match example.net's key makes every validating resolver return SERVFAIL, with EDE 9: DNSKEY Missing. Your whole domain disappears for everyone who validates, while it still works for everyone who doesn't, which makes it confusing to diagnose.

The tell-tale test is dig +cd (checking disabled). It asks the resolver to skip validation: if +cd returns an answer and a plain query returns SERVFAIL, the problem is DNSSEC, not reachability.

Caches everywhere

The authoritative server caches too. When the DS was changed with pdnsutil, the lab root kept serving the old record from its packet cache until pdns_control purge cleared it. These defaults explain most "my change didn't take" moments:

SettingDefaultEffect
cache-ttl20 sAnswers served from the packet cache after a change
query-cache-ttl / negquery-cache-ttl20 s / 60 sBackend lookups (and misses) cached
zone-cache-refresh-interval300 sNew zones from pdnsutil aren't served until then (or a restart)
xfr-cycle-interval60 sHow often changed serials trigger NOTIFY

On the recursor, rec_control wipe-cache example.net$ removes a zone's names from its cache. Changes made through the API clear the authoritative caches themselves.

Symptom, cause and fix

SymptomCauseFix
pdns won't start: no backends configuredEmpty launch= (the Debian default)Configure a backend in pdns.d/
REFUSED for a zone you just createdThe zone cache hasn't refreshedRestart, wait 5 minutes, or create zones through the API
REFUSED for names you don't hostAuthoritative servers don't recurseCorrect: point clients at the resolver
Secondary: Not Authorized; primary: client IP has no permissionSecondary not in allow-axfr-ipsAdd it, then pdns_control retrieve on the secondary
Secondary has an old serialNo NOTIFY yet (60 s check), zone kind Native, or the serial wasn't bumpedWait, pdns_control notify, set-kind primary, increase-serial
secure-zone: No backend was able to securegsqlite3-dnssec not setSet it on every server
SERVFAIL, EDE 22 No Reachable AuthorityResolver can't or won't reach the serversCheck routing and firewalls (in a lab, dont_query)
SERVFAIL, EDE 10 RRSIGs Missing for internal namesUnsigned internal zone under a signed public zoneNegative trust anchor, or sign and delegate it
SERVFAIL, EDE 9 DNSKEY Missing; +cd worksParent's DS doesn't match the zone's keyPublish the correct DS, then wait out the old one's TTL
Timeout from outside the officeClient not in the recursor's allow_fromCorrect for outsiders; check the client's address
A wrong DS at the parent (real output)
root@rootns:~# pdnsutil replace-rrset net example DS 3600 '18425 13 2 0000000000000000000000000000000000000000000000000000000000000000' >/dev/null && pdnsutil rectify-zone net >/dev/null && pdns_control purge
Adding NSEC ordering information for zone 'net', 11 updates
23

root@recursor:~# rec_control wipe-cache example.net$
wiped 6 records, 0 negative records, 1 packets

root@client:~# dig www.example.net

; <<>> DiG 9.20.29-1~deb13u1-Debian <<>> www.example.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 44395
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
; EDE: 9 (DNSKEY Missing)
;; QUESTION SECTION:
;www.example.net.		IN	A

;; Query time: 1 msec
;; SERVER: 10.10.0.53#53(10.10.0.53) (UDP)
;; WHEN: Wed Oct 21 05:47:07 UTC 2026
;; MSG SIZE  rcvd: 50


root@client:~# dig www.example.net +cd +short
203.0.113.80

root@rootns:~# pdnsutil replace-rrset net example DS 3600 '18425 13 2 9b98e79540d98caeb43674c9a6530ecbaa8ea151d501fb8c99819c15154bdd92' >/dev/null && pdnsutil rectify-zone net >/dev/null && pdns_control purge
Adding NSEC ordering information for zone 'net', 11 updates
5

root@recursor:~# rec_control wipe-cache example.net$
wiped 6 records, 0 negative records, 2 packets

root@client:~# dig www.example.net | grep -E "status|flags"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17324
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
; EDNS: version: 0, flags:; udp: 512
  • Lines 1–3: A DS that doesn't match example.net's key, then clear the root server's cache.
  • Lines 5–6: Clear the recursor's cached copy of example.net.
  • Line 13: SERVFAIL for a perfectly healthy zone…
  • Line 18: …because the parent points at a key the zone doesn't have.
  • Lines 28–29: With validation turned off (+cd), the answer is there: the problem is DNSSEC.
  • Lines 31–40: The correct DS restored: validated again.
The authoritative server's cache timers (real output)
root@rootns:~# pdns_server --config=default 2>/dev/null | grep -E "^# (cache-ttl|negquery-cache-ttl|query-cache-ttl|zone-cache-refresh-interval|xfr-cycle-interval)="
# cache-ttl=20
# negquery-cache-ttl=60
# query-cache-ttl=20
# xfr-cycle-interval=60
# zone-cache-refresh-interval=300
  • Lines 2–6: Why changes made with pdnsutil can take a little while to appear.

Check your understanding

Users say example.net is down, but it works from your laptop, which doesn't validate DNSSEC. dig +cd through the office resolver returns the address; a plain query returns SERVFAIL. What's the most likely cause?

  • A DNSSEC problem, such as a DS at the parent that no longer matches the zone's key.
  • The authoritative servers are unreachable.
  • The resolver's allow_from excludes the users.
  • The secondary hasn't transferred the zone.