IPv6-Only Network Connectivity Failures

Advanced Connectivity

Devices on an IPv6-only network (or a network with broken IPv4 fallback) experience connectivity failures to services that do not support IPv6, or suffer from Happy Eyeballs algorithm failures where IPv6 preference causes delays connecting to dual-stack hosts. Diagnosing IPv6-only failures requires understanding address types, prefix delegation, NDP, and the interaction between IPv6 and DNS AAAA records.

Symptoms

  • Only sites with AAAA (IPv6) DNS records are reachable; IPv4-only sites time out
  • Connections to dual-stack servers are slow to establish (3-5 second delay) due to IPv6 preference with Happy Eyeballs fallback
  • DHCPv6 or SLAAC fails to assign a valid global unicast address (devices only have link-local fe80:: addresses)
  • IPv6 prefix delegation from ISP is not being propagated to downstream devices by the router
  • ping6 to the gateway succeeds but ping6 to an external IPv6 address (2001:4860:4860::8888) fails
  • Router advertisements (RA) from the upstream router are being blocked or contain incorrect prefix information

Possible Root Causes

  • Router not forwarding DHCPv6 Prefix Delegation (DHCPv6-PD) from ISP to downstream devices via SLAAC/RA
  • ip6tables (IPv6 firewall) defaulting to REJECT or DROP policy while iptables (IPv4) is configured correctly
  • ISP tunnel broker (6in4, 6to4, Teredo) has failed or has increased latency, degrading IPv6 path quality
  • MTU mismatch on the IPv6 path — ICMPv6 'Packet Too Big' messages being filtered, causing PMTUD blackhole
  • DNS64/NAT64 misconfiguration on IPv6-only networks causing synthesis failures for IPv4-only destinations

Diagnosis Steps

Step 1: Verify IPv6 address assignment

# Linux
ip -6 addr show
# Look for:
# - fe80::/10 link-local (always present when IPv6 is enabled)
# - 2001::/32 or similar global unicast (required for internet access)
# - fd00::/8 unique local (private, like IPv4 RFC1918)

# macOS
ifconfig en0 | grep inet6

# Windows
ipconfig /all | findstr -i "IPv6"

A device with only fe80:: addresses has IPv6 enabled but has not received a global prefix from SLAAC or DHCPv6.

Step 2: Check for Router Advertisement reception

# Linux — monitor for Router Advertisements
sudo radvdump          # if installed
# or
sudo tcpdump -i eth0 icmp6 and 'ip6[40] == 134'
# ICMPv6 type 134 = Router Advertisement

# Alternatively, check the kernel routing table for a default IPv6 route
ip -6 route show default
# Expected: default via fe80::1 dev eth0 proto ra

No default IPv6 route via RA means no Router Advertisement is being received.

Step 3: Test IPv6 connectivity in layers

# Test 1: Link-local ping to gateway (requires knowing gateway's link-local address)
ping6 -c 4 fe80::1%eth0   # append %interface to scope link-local addresses

# Test 2: Global unicast ping to well-known IPv6 address
ping6 -c 4 2001:4860:4860::8888   # Google's IPv6 DNS

# Test 3: IPv6 DNS resolution
dig AAAA google.com
dig AAAA google.com @2001:4860:4860::8888

# Test 4: Traceroute over IPv6
traceroute6 2001:4860:4860::8888
# or
traceroute -6 google.com

Step 4: Diagnose prefix delegation issues

# Check if your router is receiving a /48 or /56 prefix from ISP via DHCPv6-PD
# On Linux router:
journalctl -u dhcpcd --no-pager | grep -i "prefix"
# or
cat /var/lib/dhcpcd/dhcpcd-eth0.lease | grep -i prefix

# Check if the router is advertising the delegated prefix downstream via RA
# On downstream device, the global address should start with the delegated prefix

Step 5: Check for IPv6 firewall rules blocking traffic

# Linux — check ip6tables rules
sudo ip6tables -L -n -v

# Look for DROP or REJECT rules that might block IPv6 traffic
# Many firewall scripts forget to configure ip6tables and default to DROP

Step 6: Test Happy Eyeballs behavior

# Use curl to force IPv4 vs IPv6 and compare connection times
time curl -4 -o /dev/null -s -w "%{time_connect}\n" https://google.com
time curl -6 -o /dev/null -s -w "%{time_connect}\n" https://google.com

# If IPv6 is significantly slower, the path has higher latency
# Check MTU issues on the IPv6 path

Step 7: Test IPv6 MTU and fragmentation

# Discover path MTU for IPv6
# IPv6 does NOT support fragmentation at routers — only at endpoints
# Default IPv6 MTU is 1280 bytes minimum; Ethernet is typically 1500

ping6 -c 4 -s 1400 2001:4860:4860::8888
ping6 -c 4 -s 1450 2001:4860:4860::8888
ping6 -c 4 -s 1500 2001:4860:4860::8888

# If larger packets fail, you have a Path MTU issue on the IPv6 path

Solution

Solution A: Enable and configure IPv6 forwarding on Linux router

# Enable IPv6 forwarding (in /etc/sysctl.conf for persistence)
sudo sysctl -w net.ipv6.conf.all.forwarding=1
echo "net.ipv6.conf.all.forwarding=1" | sudo tee -a /etc/sysctl.conf

# Configure radvd to advertise the delegated prefix downstream
# /etc/radvd.conf:
interface eth1 {
    AdvSendAdvert on;
    MinRtrAdvInterval 3;
    MaxRtrAdvInterval 10;
    prefix 2001:db8::/64 {
        AdvOnLink on;
        AdvAutonomous on;
    };
};

Solution B: Fix ip6tables to allow IPv6 traffic

# Allow established connections and essential ICMPv6 (required for IPv6 to function)
sudo ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo ip6tables -A INPUT -p icmpv6 -j ACCEPT
sudo ip6tables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo ip6tables -A FORWARD -p icmpv6 -j ACCEPT
sudo ip6tables -P FORWARD ACCEPT   # or set appropriate policy

# Save rules
sudo ip6tables-save > /etc/ip6tables.rules

Solution C: Fix MTU for IPv6 tunnels

# If using a 6in4 tunnel, the effective IPv6 MTU is reduced by 20 bytes (IPv4 header)
# Set tunnel MTU to 1480 instead of 1500
sudo ip link set sit0 mtu 1480

# For physical interfaces, set to 1500 if not already
sudo ip link set eth0 mtu 1500

Solution D: Configure DNS64 for IPv6-only networks

On an IPv6-only network, a DNS64 server synthesizes AAAA records for IPv4-only domains:

# Test if your network provides DNS64 by looking for synthesized AAAA records
dig AAAA ipv4only.arpa @your-dns-server
# A synthesized address starts with 64:ff9b::/96 (NAT64 well-known prefix)

Prevention

  • Test your IPv6 configuration with tools like https://test-ipv6.com after any network changes to catch issues before users are affected
  • Ensure all firewall automation scripts configure ip6tables in parallel with iptables — IPv6 traffic is separate and must be explicitly allowed
  • Request a /48 or /56 prefix delegation from your ISP to ensure stable addressing that survives router reboots
  • Enable IPv6 address privacy extensions (RFC 4941) to rotate temporary addresses for outbound connections while keeping stable addresses for inbound
  • Monitor both A and AAAA DNS records for your services to ensure IPv6 reachability does not silently degrade

Related Protocols

Related Terms

More in Connectivity