← Back to Learning Hub

DNS • Intermediate • 5 min read

EDNS0 Explained: DNS Message Size, Truncation, and TCP Fallback

EDNS0 (RFC 6891) lets DNS exceed 512 bytes. Learn the OPT record, why 1232 bytes is the safe default, how the TC bit forces TCP fallback, and how to test it.

The original DNS protocol from 1987 capped a UDP response at 512 bytes and offered no way to advertise support for new features. That ceiling became a real problem as DNSSEC signatures, IPv6 records, and larger answer sets pushed responses well past 512 bytes. EDNS0, the Extension Mechanisms for DNS defined in RFC 6891, is the backward-compatible fix. It lets a client tell the server how large a UDP response it can accept and carries flags and option codes for features the base protocol never imagined. This guide explains how EDNS0 advertises buffer size, why 1232 bytes became the safe default, how truncation triggers a TCP retry, and how to diagnose the whole chain with dig.

The 512-byte problem

In classic DNS, a response that would not fit in 512 bytes of UDP payload had to set the TC (truncated) bit, signaling the client to retry over TCP. That worked, but it was slow and many naive firewalls wrongly assumed DNS was UDP only and dropped TCP port 53. Meanwhile responses kept growing. A single DNSSEC-signed answer with an RRSIG and a DNSKEY set can run to several kilobytes. Without a way to negotiate larger UDP payloads, every signed lookup would fall back to TCP, roughly doubling round trips.

How EDNS0 works: the OPT pseudo-record

EDNS0 does not add new header fields, which would have broken old servers. Instead it smuggles its data into a special resource record called OPT, placed in the additional section of the message. OPT is a pseudo-record: it is never stored in a zone and never cached. It repurposes the usual RR fields to carry EDNS metadata.

Classic RR fieldEDNS0 use in the OPT record
NAMEAlways root (empty)
TYPE41 (OPT)
CLASSRequestor's UDP payload size (buffer the sender can accept)
TTLExtended RCODE, EDNS version, and flags such as DO (DNSSEC OK)
RDATAVariable list of options (code, length, value) like cookies or client subnet

The most important value for sizing is the UDP payload size carried in the CLASS field. When a resolver sends a query, it says, in effect, "I can accept a UDP answer up to N bytes." The server honors that limit and only sets the TC bit if even N bytes is not enough.

Why 1232 bytes is the modern default

For years many resolvers advertised 4096 bytes, the maximum RFC 6891 mentions. That turned out to cause real breakage. UDP datagrams larger than the network path MTU get fragmented at the IP layer, and fragmented UDP is frequently dropped by firewalls and is a security risk for spoofing. The result was mysterious timeouts on large, often DNSSEC-signed, answers.

DNS Flag Day 2020 recommended that resolvers and authoritative servers default to an EDNS buffer size of 1232 bytes. The number is not arbitrary: it is the IPv6 minimum MTU of 1280 bytes minus 48 bytes for the IPv6 and UDP headers, which keeps a DNS datagram from fragmenting on essentially any modern path. Anything larger than what fits is signaled with TC and retried over TCP, which handles big payloads reliably.

  • 512 bytes: the pre-EDNS hard limit, still the fallback when no OPT record is present.
  • 1232 bytes: the DNS Flag Day 2020 recommended default, fragmentation-safe.
  • 1400 to 1452 bytes: common older defaults tuned to IPv4 Ethernet MTU, riskier on mixed paths.
  • 4096 bytes: the legacy maximum that caused fragmentation problems; now discouraged as a default.

Truncation and the TCP fallback dance

When a server cannot fit an answer within the client's advertised UDP size, it returns a short response with the TC bit set. A well-behaved resolver then reissues the identical query over TCP, where the message length is prefixed by a two-byte field and can be far larger. The sequence is:

  1. Client sends a UDP query with an OPT record advertising, say, 1232 bytes.
  2. Server has a 1500-byte answer, so it replies over UDP with TC set and little or no answer data.
  3. Client sees TC and opens a TCP connection to port 53.
  4. Client re-sends the query over TCP; server streams the full answer.

This is exactly why blocking TCP port 53 breaks DNS for large answers even though simple lookups keep working. If you run authoritative or recursive servers, TCP 53 must be open.

Seeing EDNS0 with dig

dig shows the OPT pseudo-record in a dedicated pseudosection. Here a normal query advertises a 1232-byte buffer:

dig +edns=0 +nocrypto example.com A

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50172
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, ADDITIONAL: 1

You can force a deliberately tiny buffer to watch truncation happen, then confirm TCP recovers the full answer:

# Force a small UDP buffer; a large signed answer gets truncated
dig +dnssec +bufsize=512 +ignore dnssec.example. DNSKEY

;; flags: qr rd ra tc; ...        <-- note the 'tc' (truncated) flag

# Same query, let dig follow TC to TCP (default), full answer returns
dig +dnssec +bufsize=512 dnssec.example. DNSKEY
;; Truncated, retrying in TCP mode.

To check whether your resolver or an on-path device supports EDNS and large answers at all, the DNS Flag Day project publishes a tester, but you can also probe directly:

# Ask for a known large, signed response over your resolver
dig +dnssec org DNSKEY @your-resolver-ip

# If you only ever see 'tc' and TCP is blocked, large answers will fail.
dig +tcp +dnssec org DNSKEY @your-resolver-ip   # should succeed

Other things EDNS0 carries

Buffer size is the headline, but the OPT record is a general extension slot. Several widely used features ride on it:

FeatureWhat it does
DO flagSignals the client wants DNSSEC records (RRSIG, NSEC) in the answer
DNS CookiesLightweight anti-spoofing token between client and server (RFC 7873)
EDNS Client SubnetPasses a truncated client network to authoritative servers for geo answers (RFC 7871)
Extended DNS ErrorsHuman-readable reason codes for failures such as filtered or stale answers (RFC 8914)

Practical guidance

  • Set EDNS buffer defaults to 1232 bytes on resolvers you control, matching the Flag Day recommendation.
  • Never block TCP port 53; truncation-driven retries depend on it.
  • Do not assume firewalls that strip EDNS or block fragments are harmless; they cause intermittent, hard-to-trace failures on exactly the largest and most security-relevant answers.
  • When debugging timeouts on signed zones, test with a small bufsize to reproduce truncation, then confirm TCP works.

EDNS0 is the quiet layer that lets modern DNS features exist without breaking thirty-year-old software. When you change resolvers, enable DNSSEC, or adjust buffer sizes, verify that answers still resolve cleanly from around the world with the Valla DNS propagation checker, and explore the Valla DNS learning hub for companion guides on DNSSEC, TTL strategy, and SOA tuning that all interact with message size and caching.

Troubleshooting box

If results look inconsistent, compare authoritative nameservers first, then recursive resolvers by region. Capture snapshots every 10 minutes for deterministic incident timelines.

Try VallaDNS free →