Why I Had to Dig Into This
I’ve been running Pi-hole for years, and DNSSEC has always been that feature I wanted to enable but couldn’t keep running. Every time I turned it on, things would break in unpredictable ways over the following days and weeks. Wikipedia wouldn’t load on iOS. Firefox sync would fail. YouTube videos wouldn’t play. Spotify couldn’t download content. The pattern was clear: DNSSEC was causing DNS resolution failures, but the failures were inconsistent and hard to reproduce.
After a few years of leaving it disabled, I decided to try again. Most of the old problems seemed gone, but a new one appeared immediately: the DNSSEC validation test site at wander.science completely stopped working. This was actually useful—I finally had a consistent, reproducible failure to investigate.
What My Setup Looked Like
My Pi-hole runs on standard hardware with two upstream DNS servers configured:
- Quad9 (9.9.9.9) – which explicitly supports DNSSEC
- Digitalcourage (5.9.164.112) – a German privacy-focused DNS service
The Pi-hole itself was fully updated, running the stable release. Nothing exotic in the configuration—just blocking, logging, and now DNSSEC enabled.
The Failure Pattern
With DNSSEC enabled, querying wander.science through Pi-hole produced one of two results:
- A timeout after 2 seconds
- An “Unspecified error” response
The Pi-hole query log showed the request reaching Quad9, but the response showed “N/A (1 reply)” for the DS record lookup. That DS record is critical—it’s part of the DNSSEC chain of trust that validates the domain’s signature.
What made this strange: when I bypassed Pi-hole and queried Quad9 directly using nslookup wander.science 9.9.9.9, it worked perfectly. Same with the other upstream server. The upstream DNS servers were fine. The problem was happening inside Pi-hole’s DNSSEC validation process.
What I Found Using delv
I switched from nslookup to delv, which is specifically designed for DNSSEC troubleshooting. Running delv @pi.hole wander.science gave me:
;; resolution failed: SERVFAIL
Using delv +rtrace to trace the full validation chain showed Pi-hole was attempting to fetch:
- The A record for wander.science
- The DNSKEY for wander.science
- The DS record for wander.science
- The DNSKEY for the parent zone (.science)
- And so on up the chain
One of those requests was timing out or returning invalid data, breaking the entire validation chain.
The Real Problem: Packet Fragmentation
After digging through forums and similar reports, I found the actual issue: DNSSEC responses are significantly larger than standard DNS responses because they include cryptographic signatures. These larger responses often exceed the standard UDP packet size of 512 bytes and require EDNS0 (Extension Mechanisms for DNS) support, which allows larger UDP packets up to 4096 bytes.
The problem wasn’t Pi-hole or the upstream DNS servers. It was my ISP’s modem.
My ISP had pushed a firmware update to my modem a few months earlier. That update apparently broke proper handling of fragmented UDP packets. When Pi-hole requested DNSSEC records and the upstream server sent back a large response (over 1500 bytes, requiring fragmentation), the modem was silently dropping or corrupting those fragmented packets.
This explained everything:
- Why direct queries to upstream servers worked from my machine (smaller responses, or my machine’s network stack handled fragments better)
- Why Pi-hole’s DNSSEC validation failed (it needed the full large responses to validate signatures)
- Why the failures were inconsistent (depended on response size for each domain)
- Why disabling DNSSEC made everything work (no large signed responses needed)
The Fix I Applied
I couldn’t roll back the modem firmware—my ISP doesn’t allow that. Instead, I configured Pi-hole to work around the fragmentation issue by limiting EDNS buffer size. I added this to /etc/dnsmasq.d/99-edns.conf:
edns-packet-max=1232
This tells Pi-hole’s underlying DNS resolver (dnsmasq) to advertise a maximum EDNS buffer size of 1232 bytes instead of the default 4096. This keeps responses small enough to fit in a single unfragmented UDP packet, even with DNSSEC signatures included.
After restarting Pi-hole’s DNS service with pihole restartdns, wander.science loaded immediately. The DNSSEC validation test passed. All the other domains that had previously caused problems worked correctly.
What I Learned
DNSSEC failures are rarely about DNSSEC itself. The validation logic is solid. The problem is almost always in the network path—routers, modems, or ISP equipment that doesn’t properly handle the larger packet sizes DNSSEC requires.
ISP modem firmware updates can break things silently. I had no indication the update caused problems until I tried enabling DNSSEC again. The modem still routed traffic, handled DHCP, and did everything else normally. It just quietly broke one specific aspect of UDP packet handling.
EDNS packet size matters more than I expected. The difference between 1232 bytes and 4096 bytes is the difference between DNSSEC working or failing on networks with broken fragmentation support. This isn’t just my ISP—it’s common enough that many public DNS resolvers now default to smaller EDNS buffer sizes.
Debugging tools matter. nslookup told me almost nothing useful. delv with +rtrace showed exactly where the validation chain was breaking. Using the right tool saved hours of guessing.
Limitations and Trade-offs
Reducing the EDNS packet size to 1232 bytes means Pi-hole can’t receive responses larger than that in a single packet. For the vast majority of domains, this isn’t a problem. But for domains with extremely large DNSSEC signatures or many DNS records, this could theoretically cause issues. I haven’t encountered any yet.
The real fix would be for my ISP to either roll back the firmware or fix the fragmentation bug. But I have no control over that, and they’re unlikely to acknowledge it’s even a problem. The EDNS workaround is good enough for my network.
If you’re experiencing similar DNSSEC failures, check your modem and router first. The problem is probably not Pi-hole.