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.com works but applications fail to resolve the domain
  • dig example.com +bufsize=512 works but dig example.com +bufsize=4096 times out
  • DNS response has the tc (truncated) flag set
  • Intermittent resolution failures that resolve when switching to TCP
  • dig example.com +tcp works but dig example.com +notcp fails

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. 1.Test if responses are being truncated:
  2. 2.```bash
  3. 3.dig example.com +noall +comments
  4. 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. 1.Test DNS-over-TCP as a fallback:
  2. 2.```bash
  3. 3.dig example.com +tcp +noall +answer
  4. 4.# If TCP works but UDP does not, the network is blocking large UDP
  5. 5.`
  6. 6.Check MTU on the network path:
  7. 7.```bash
  8. 8.# Test MTU to the DNS server
  9. 9.ping -M do -s 1472 8.8.8.8
  10. 10.# If this fails, reduce the size until it works
  11. 11.ping -M do -s 1400 8.8.8.8
  12. 12.`
  13. 13.Configure the DNS resolver to use smaller EDNS0 buffer size:
  14. 14.```bash
  15. 15.# For BIND (named.conf options):
  16. 16.options {
  17. 17.edns-udp-size 1232; # Default is 4096
  18. 18.max-udp-size 1232;
  19. 19.};
  20. 20.sudo systemctl restart named

# For Unbound (unbound.conf): edns-buffer-size: 1232 sudo systemctl restart unbound ```

  1. 1.Fix the firewall to allow fragmented UDP or DNS-over-TCP:
  2. 2.```bash
  3. 3.# Allow DNS-over-TCP (port 53 TCP)
  4. 4.sudo iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
  5. 5.sudo iptables -A INPUT -p tcp --sport 53 -j ACCEPT

# Allow UDP fragmentation reassembly sudo iptables -A INPUT -f -j ACCEPT ```

  1. 1.For systems using systemd-resolved, configure the DNS stub:
  2. 2.```bash
  3. 3.sudo nano /etc/systemd/resolved.conf
  4. 4.# Add:
  5. 5.DNSStubListenerExtra=
  6. 6.# Restart to apply
  7. 7.sudo systemctl restart systemd-resolved
  8. 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