You enabled IPv6 on a Friday afternoon. The change window was clean, the ip -6 addr output looked right, smoke tests passed. By Monday, half your monitoring was green and lying to you. Your blackbox exporter was happily probing https://10.0.4.12/health over IPv4 while user traffic from mobile carriers — which are all v6-first now — fell over a cliff on a path your dashboards never touched.
That is the defining property of dual-stack failure: it doesn't break IPv4 loudly. It breaks it silently, by making IPv6 preferred (RFC 6724 address selection) and then failing on a path nobody instrumented. A broken v6 route doesn't lose to a working v4 route — it wins, and then it times out.
This guide is for sysadmins, SREs, and network/security engineers running real infrastructure. By the end you'll have working configs for Linux hosts, nginx, HAProxy, systemd-resolved, and nftables, plus a rollout order that keeps you off the 3am page. The thesis throughout: dual-stack is a policy problem disguised as a config problem. Happy Eyeballs, DNS AAAA leaks, and asymmetric firewall rules are where you actually get burned — not in ip addr add.
:::note[TL;DR]
- IPv6 is preferred by the kernel's address selection; a broken v6 path silently beats a working v4 path. Instrument both or you're blind.
- Write your firewall once in the
inetfamily. Two parallel rule sets is a drift bug waiting to happen. - AAAA is a traffic switch. Sequence it: infra → monitoring → internal DNS → canary → full publish.
- Never block ICMPv6 types 1–4 and 128–136. You will break PMTUD and neighbor discovery.
- Have a five-minute AAAA rollback before you publish anything. :::
Prerequisites
- A Linux host with a v6-capable kernel (any modern distro; check
ip -6 addrreturns something). -
nftables(the default on current Debian/Ubuntu/RHEL families;iptables-nftshim is fine but write nativenft). -
nginxand/orhaproxyif you're fronting traffic. -
systemd-resolvedor a resolver you control, for split-horizon testing. - A lab GUA (global unicast) allocation or a Hurricane Electric tunnel if your uplink has no native v6. Do not test on production first.
1. Why Dual-Stack Fails Quietly
The failure mode is baked into the standard. When a host resolves both an A and an AAAA record, the kernel's getaddrinfo ordering (RFC 6724) puts IPv6 first. Applications that don't implement Happy Eyeballs — and plenty don't — connect to the v6 address, wait for the TCP timeout, and never fall back. Even Happy Eyeballs is a client-side heuristic with roughly a 250ms head start, not a contract; servers and middleboxes still lie about reachability.
The three silent killers:
- Happy Eyeballs is not a guarantee. It's a race with a head start. If your v6 path black-holes packets (as opposed to sending RST), the client may still win the race to a broken socket.
- DNS AAAA asymmetry. Your internal resolver hands out AAAA for a host that has no v6 route back. Traffic goes into a hole.
- Firewall default-deny on v6 only. You carried v4 rules over but never wrote v6 equivalents — so v6 is either silently wide open or fully blocked, depending on your default policy.
Before anything else, confirm the kernel is actually doing v6 and understand what an address/route looks like:
# Confirm v6 is enabled and see the address + route reality sysctl net.ipv6.conf.all.disable_ipv6 ip -6 addr show dev eth0 ip -6 route show default ⚠️ TRUNCATED VERSION
This is an abbreviated cross-post. Full article (all config files, architecture diagrams, images): valtersit.com
🛠️ Partner Tools for Developers
ValtersIT curates partner deals for developers and sysadmins — VPS hosting, security tools, monitoring platforms and dev productivity gear. No filler, no affiliate spam.

