Introduction
EDNS0 (Extension Mechanisms for DNS) allows DNS responses larger than the original 512-byte UDP limit by negotiating a larger buffer size between the client and server. When a firewall, NAT device, or MTU misconfiguration blocks or fragments large UDP packets, DNS responses get truncated. The resolver should fall back to TCP, but many firewalls also block DNS-over-TCP, causing complete resolution failure for domains with large DNS responses (many TXT records, DKIM keys, SPF records).
Symptoms
dig example.comworks but applications fail to resolve the domaindig example.com +bufsize=512works butdig example.com +bufsize=4096times out- DNS response has the
tc(truncated) flag set - Intermittent resolution failures that resolve when switching to TCP
dig example.com +tcpworks butdig example.com +notcpfails
Common Causes
- Firewall blocking UDP packets larger than 512 bytes
- MTU misconfiguration causing fragmentation of large DNS responses
- Authoritative server sending responses larger than the client's advertised buffer
- DNS resolver not falling back to TCP when response is truncated
- VPN or tunnel reducing effective MTU below what DNS responses require
Step-by-Step Fix
- 1.Test if responses are being truncated:
- 2.```bash
- 3.dig example.com +noall +comments
- 4.# Look for: ";; flags: qr rd ra tc;" - tc means truncated
# Test with different buffer sizes dig example.com +bufsize=512 +noall +comments dig example.com +bufsize=1232 +noall +comments dig example.com +bufsize=4096 +noall +comments ```
- 1.Test DNS-over-TCP as a fallback:
- 2.```bash
- 3.dig example.com +tcp +noall +answer
- 4.# If TCP works but UDP does not, the network is blocking large UDP
- 5.
` - 6.Check MTU on the network path:
- 7.```bash
- 8.# Test MTU to the DNS server
- 9.ping -M do -s 1472 8.8.8.8
- 10.# If this fails, reduce the size until it works
- 11.ping -M do -s 1400 8.8.8.8
- 12.
` - 13.Configure the DNS resolver to use smaller EDNS0 buffer size:
- 14.```bash
- 15.# For BIND (named.conf options):
- 16.options {
- 17.edns-udp-size 1232; # Default is 4096
- 18.max-udp-size 1232;
- 19.};
- 20.sudo systemctl restart named
# For Unbound (unbound.conf): edns-buffer-size: 1232 sudo systemctl restart unbound ```
- 1.Fix the firewall to allow fragmented UDP or DNS-over-TCP:
- 2.```bash
- 3.# Allow DNS-over-TCP (port 53 TCP)
- 4.sudo iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
- 5.sudo iptables -A INPUT -p tcp --sport 53 -j ACCEPT
# Allow UDP fragmentation reassembly sudo iptables -A INPUT -f -j ACCEPT ```
- 1.For systems using systemd-resolved, configure the DNS stub:
- 2.```bash
- 3.sudo nano /etc/systemd/resolved.conf
- 4.# Add:
- 5.DNSStubListenerExtra=
- 6.# Restart to apply
- 7.sudo systemctl restart systemd-resolved
- 8.
`
Prevention
- Set EDNS0 buffer size to 1232 bytes (the safe maximum for IPv4 with standard MTU)
- Ensure firewalls allow DNS-over-TCP as a fallback for large responses
- Monitor DNS response sizes and alert when they approach EDNS0 limits
- Use DNS response compression to reduce response sizes
- Configure MTU correctly on all network interfaces, especially VPN tunnels