A DNS name carrying several large TXT records resolves on most networks but times out behind one firewall; how do EDNS0's advertised UDP size, IP fragmentation and TCP fallback explain it?
answer
- a pseudo-record in the additional section
- the requester's size rides in CLASS
- bigger than the path MTU
- fragments that never arrive
- no reply means no TC bit
basics
~20 sThe resolver's EDNS0 OPT record advertises a large UDP size, so the server sends the answer untruncated; above the path MTU it is fragmented, the firewall drops the fragments, and with no reply there is no TC bit to prompt a TCP retry.
solid answer
~50 sEDNS0 (RFC 6891) adds an `OPT` pseudo-record, type 41, to the additional section; its CLASS field carries the requester's UDP payload size. If the resolver advertises 4096 bytes, a server holding a 3,000-byte `TXT` answer sends it in one UDP datagram without truncation. On a 1,500-byte-MTU path IP must fragment it, and a firewall that drops fragments delivers nothing: the resolver times out, and because no response arrived it never sees `TC=1` and never retries over TCP. The fix is to advertise a size that avoids fragmentation, which RFC 6891 itself asks for behind such firewalls. 1232 bytes is the common operational choice from the 2020 DNS flag day (the 1,280-byte IPv6 minimum MTU minus 40 bytes of IPv6 header and 8 of UDP), not an RFC value. Large answers then come back truncated and retry over TCP, so TCP 53 must be open too.
go deeper
Recall that EDNS0 lets a DNS client say it can accept UDP answers larger than 512 bytes, using an OPT pseudo-record in the additional section.
Explain the OPT record: type 41, the requester's UDP payload size in its CLASS field, values under 512 treated as 512, and FORMERR without OPT from servers that lack EDNS0.
Show the diagnosis: a name-specific timeout for large answers points at fragments dropped on the path; advertise a fragment-free size such as the operational 1232 and make sure TCP 53 is open.
Weigh the size choice as a fleet policy: larger buffers mean fewer TCP connections but more fragmentation risk, smaller ones shift load to TCP. Decide with measurements of your paths, not an RFC default.
## The OPT pseudo-record **EDNS0** (Extension Mechanisms for DNS, version 0, RFC 6891) lets a DNS requester and responder exchange capabilities without changing the 12-byte header. It does this with a **pseudo-record**: an `OPT` record, **type 41**, placed in the **additional section**. It carries no DNS data; it describes this one transaction. | OPT field | Holds | |---|---| | NAME | the root name (empty) | | TYPE | `OPT` (41) | | CLASS | the **requester's UDP payload size**: the largest UDP payload it can reassemble and deliver | | TTL | the extended rcode bits, the EDNS version and flags | | RDATA | zero or more options as attribute-value pairs | Rules that shape behaviour: - A responder that understands EDNS0 and receives an `OPT` **MUST include one** in its response, and only one `OPT` may appear in a message. - `OPT` records **MUST NOT be cached, forwarded or stored**; each hop negotiates for itself, and the requester's advertised size must not be cached beyond its transaction. - Advertised sizes **below 512 are treated as 512**. - A server that does not implement EDNS0 answers an `OPT`-bearing query with `FORMERR` and **no** `OPT`, so the requester can fall back to plain DNS and its 512-byte limit. ## How a large answer travels Suppose `example.com` publishes several long `TXT` strings totalling about 3,000 bytes. **Resolver advertises 4096 bytes:** 1. The query leaves over UDP with an `OPT` saying 4096. 2. The answer fits within 4096, so the server sends it whole, with `TC` clear. 3. The IP packet exceeds the path MTU (1,500 bytes on typical Ethernet) and is **fragmented**. 4. A firewall on the path drops fragments; the resolver receives nothing usable. 5. The resolver **times out**. Since no reply arrived, it never saw `TC=1`, so it has no signal to retry over TCP. **Resolver advertises 1232 bytes:** 1. The query leaves with an `OPT` saying 1232. 2. The answer does not fit, so the server returns a truncated reply with `TC=1`; RFC 6891 requires even a truncated reply to carry the header, the question and an `OPT`. 3. That small reply crosses the firewall unfragmented. 4. The resolver re-asks over **TCP port 53** and receives the full answer, which TCP segments without IP fragmentation. The same name works on other networks because their paths deliver fragments, or have no such firewall. ## Why the failure is a timeout, not an error Nothing on the wire says "too big". The server believes it answered. The firewall drops silently. From the resolver's side the symptom is identical to packet loss, so the usual reaction is to retransmit the same query, which fails the same way. RFC 6891 permits a requester to fall back to smaller advertised sizes after failures; whether and how quickly a resolver does so is an **implementation choice**, which is why the symptom can range from a slow success to a hard timeout. ## Choosing the advertised size - **RFC 6891 (2013)** says the requester SHOULD advertise a size it can actually receive, and SHOULD NOT choose one that causes fragmentation if it sits behind a firewall that blocks fragments. It suggests 4096 as a starting point, falling back to around 1280-1410 bytes, then 512. - **Operational practice moved lower.** RFC 7766 records that IP fragmentation "has been found to be unreliable in many circumstances". The **2020 DNS flag day** recommended **1232 bytes**: the IPv6 minimum MTU of 1,280 (RFC 8200) minus 40 bytes of IPv6 header and 8 of UDP header. That is an operational recommendation, not a number from any RFC. - **Smaller sizes cost TCP.** RFC 6891 warns that too small a value pushes more answers to TCP, with the extra load that brings, which matters most for large signed answers. ## Other ways the same name can fail | Cause | Symptom | |---|---| | Fragments dropped on the path | timeout for large answers only | | TCP port 53 blocked | `TC=1` arrives, then the TCP retry fails | | A middlebox that drops packets carrying EDNS0 options (noted in RFC 7766) | timeouts that disappear without EDNS0 | | Responder without EDNS0 support | `FORMERR` with no `OPT`; the requester retries without EDNS0 | ## Common misconceptions - **"Bigger buffers are always better."** Above the path MTU they trade truncation for fragmentation. - **"The server will notice and resend with TC."** It cannot notice a drop downstream. - **"EDNS0 made TCP unnecessary."** It made truncation rarer; TCP is still the path for answers that do not fit.
- What does a DNS server that does not implement EDNS0 do with a query carrying an OPT record?RFC 6891 says it MUST answer `FORMERR` and MUST NOT include an `OPT` record. A server that does implement EDNS0 but finds the `OPT` malformed also returns `FORMERR`, but with an `OPT` included. That difference lets the requester tell an old server from a bad option; for the old server it retries without EDNS0 and accepts the 512-byte limit.
- Why not have a DNS resolver advertise 65,535 bytes so nothing is ever truncated?RFC 6891 advises against advertising an architectural limit. A very large value guarantees IP fragmentation, so one lost fragment or one firewall that drops fragments loses the whole answer, and buffers that large cost memory low in the stack. The advertised size should be one the requester can actually receive end to end.
- Can a DNS server remember a client's advertised EDNS0 size and reuse it for later queries?No. RFC 6891 says the requester's maximum payload size can change and MUST NOT be cached beyond the transaction in which it is advertised, and `OPT` records MUST NOT be cached, forwarded or stored. Each query carries its own `OPT`, and a forwarding resolver advertises its own size upstream rather than passing the client's along.
saying these in an interview costs you the question
- RFC 6891 requires every resolver to advertise a 1232-byte EDNS0 buffer.
- A bigger advertised EDNS0 size is always better because it avoids TCP.
- If the fragmented answer is dropped, the server resends it with TC set.
- The OPT record is cached together with the answer it arrived with.
- Opening UDP port 53 is all a firewall needs to allow for DNS.
- EDNS0 raised the UDP limit, so TCP fallback is no longer needed.