TL;DR
- Until today our resolver filled a truncated UDP datagram with 1,023 to 1,256 bytes before setting the TC bit. Google, Cloudflare and Quad9 send a bare header on the same names. As of 1 September 2026 we send one too.
- Fifteen of the eighteen names in our own census dropped from 1,023-1,256 bytes to 63-71. Re-measured with the published script, from the same host, after the deploy.
- Our worst case is unchanged at 20.1×, and that is not a failure of the change. The three names that still come back whole are the ones small enough to fit, and no resolver truncates what fits. Google and Cloudflare sit at 19.6× on the same names.
- The residual 28 bytes is our DNS Cookie, measured rather than assumed: aol.com is 1,256 bytes with it and 1,228 without, which is byte-for-byte Google's number.
- A correction in the same pass. We wrote that Cloudflare and Quad9 behave identically to Google. Quad9 truncates paypal.com to 39 bytes where the other two send all 1,237.
What the clamp was not doing
The EDNS buffer clamp we deployed in July decides when an answer is truncated. It says nothing about how much of the answer is reflected once that decision is made, and the census we published on 31 August in Is Your AdGuard Home or Pi-hole a DNS Amplification Weapon? is what made the difference visible: on the fourteen fattest TXT names, Google returned 35 to 43 bytes and we returned over a thousand.
RFC 2181 section 9 settles which of the two is right, and it settled it in 1997: the partial record set may be left in the response, and a client receiving TC is told to ignore that response and ask again over TCP. May, not must - and the bytes are to be thrown away unread. So nothing legitimate loses anything when they are not sent. The only party who gets value from them is the one who never asked.
The change
In our dnsproxy fork, once TC is set on a plain-UDP answer the answer, authority and additional sections are dropped and only the OPT record survives. OPT is kept deliberately: it carries the DNS Cookie the client needs for return-routability on the TCP retry, and the EDNS echo RFC 6891 requires. TCP, DoT, DoQ and DoH are structurally unaffected, because TC is never set on any of them.
Before and after, same script, same host
Measured from a second machine, not from the resolver itself - this one drops fragmented UDP inbound, so a census run on it prints zeroes that read like refusals.
- cisco, sony, adobe, intel, amazon, microsoft, hp, samsung, oracle, ibm, salesforce, ebay, cloudflare, apple, paypal - 63 to 71 bytes each, where they were 1,023 to 1,256.
- aol.com 1,256, google.com 1,215, yahoo.com 824 - unchanged, because they fit under the clamp and are never truncated at all.
One mismatch to expect if you run it yourself against both: our google.com row reads 1,215 bytes against their 1,103. That is not a size behaviour. We return seventeen TXT records for the name where Google, Cloudflare and Quad9 all return sixteen, and one extra TXT record is 112 bytes - which looks exactly like a truncation difference until you count records.
Correction, a few hours after this went up. This paragraph first said the extra record was one Google had added and the others had not caught up with, and called it cache freshness. Both halves were wrong, and the first was backwards. All four of google.com's authoritative servers return sixteen TXT records and none publishes the extra name, so it is a record that has been withdrawn and that we are still handing out. Nor is it stale in our own cache: watching the TTL count down, cross zero and reset, the record comes back on the fresh fetch, at the edge and at the layer below it. Something upstream of our caches is supplying it on every refresh, and from this vantage we could not identify which resolver, so we are not naming one.
One number that is still over our own clamp
Our aol.com answer is 1,256 bytes, which is 24 more than the 1,232 we advertise. The message is 1,228 before the cookie and fits; the server cookie is appended after the truncation budget has been decided, so an answer that only just fits can end up over. It is unreachable through the truncation path, which needs an answer that is truncated at all, and the same slack shows in Google's and Cloudflare's 1,237-byte paypal.com. It is recorded as an open item rather than fixed, because the fix belongs in the cookie path.
The same 28 bytes cut the other way on paypal.com: 1,237 plus a cookie is 1,265, over the clamp, so we truncate to 67 bytes a name that Google and Cloudflare send whole.
The correction
The census section said, of Google's bare-header behaviour, that "Cloudflare and Quad9 behave identically". Cloudflare does, row for row. Quad9 does not: it truncates paypal.com to 39 bytes where Google and Cloudflare both send all 1,237. That is the only disagreement among the three across eighteen names, and the sentence is now corrected on the page rather than removed from it. The full census, the resolver comparison table and the dated update all sit in the amplification runbook.