IPv6 leak prevention for VPN users and operators
Why IPv6 leaks happen on dual-stack systems, when disabling IPv6 is only a workaround, and how to fix the problem properly.
"Disable IPv6" is a workaround, not a worldview.
It is a good emergency move sometimes. It is also the laziest sentence in the entire VPN industry. Most guides say it as if they have explained the problem. They have not. They have only described one way to stop seeing the problem for a while.
The real issue is simpler and less flattering: if your host is dual-stack and your VPN story only protects IPv4, then your IPv6 traffic may keep using the ordinary network. You did not build a private tunnel. You built a half-tunnel and then hoped address families would be polite enough to ignore the gap.
They will not.
How the leak actually happens
The IETF's draft on VPN leakages in dual-stack hosts and networks says the problem plainly: IPv4-only VPN software does nothing to secure IPv6 traffic on dual-stacked hosts and networks.
That is the core operator rule.
If:
- the host has IPv6 connectivity
- the network is dual-stack
- the VPN only handles IPv4
then IPv6 traffic can continue outside the tunnel in the clear.
This is not a niche paper-cut anymore. The 2025 measurement study Smoothing Rough Edges of IPv6 in VPNs found native IPv6 leakage at meaningful rates among users of IPv4-only VPNs. The broad lesson is not "some providers were sloppy." It is that dual-stack is normal now, and pretending only IPv4 matters creates predictable failure.
The dangerous state is false confidence
People often talk about IPv6 leaks as if "IPv6 enabled" is the dangerous state.
It is not.
The dangerous state is:
- IPv6 enabled
- local network still advertising IPv6 paths
- VPN config written as if IPv6 did not exist
- operator assuming the tunnel is full because IPv4 looks clean
That is why leak prevention belongs next to /blog/network-opsec-checklist, not in a separate optional bucket. If the tunnel carries v6, your full-tunnel story needs ::/0. If it does not, you need to disable IPv6 intentionally and verify that it stayed off.
The mushy middle is what leaks.
Router Advertisements are not background noise
One reason IPv6 leaks surprise people is that the local network keeps helping.
The Linux kernel's IP sysctl documentation documents accept_ra, which controls whether Router Advertisements are accepted and used for autoconfiguration. It also documents accept_ra_defrtr, which determines whether default routers learned from RAs are installed.
That is not just protocol trivia. It is one of the concrete ways a local network can hand your machine a perfectly valid IPv6 route that has nothing to do with your VPN.
In plain English:
- the LAN says "here is your IPv6 world"
- the host believes it
- the VPN only captures IPv4
- traffic follows the route that exists
This is why dual-stack leaks are often rediscovered after a Wi-Fi change, resume from sleep, or router change. The local network has opinions, and IPv6 autoconfiguration is good at reasserting them.
Audit the relevant knobs:
sysctl net.ipv6.conf.all.accept_ra
sysctl net.ipv6.conf.default.accept_ra
If you do not know how your host is learning IPv6 routes, you are not done hardening.
The two sane outcomes
There are really only two defensible states.
1. Tunnel IPv6 correctly
If your VPN supports IPv6, treat it like a first-class routing problem. For a full-tunnel WireGuard setup, that usually means:
[Peer]
AllowedIPs = 0.0.0.0/0, ::/0
The wg-quick(8) man page specifically calls out special handling for default routes, including ::/0. If your tunnel is supposed to carry IPv6 but your config forgot the IPv6 default route, you did not build a full tunnel. You built a confidence trick.
This is the proper fix when the service, infrastructure, and threat model actually support v6 cleanly.
And "support v6 cleanly" means more than assigning an IPv6 address to the tunnel interface and calling it a day. The 2025 measurement paper found that many users of dual-stack VPNs still preferred IPv4 instead of the VPN-assigned IPv6 path because address-selection behavior and surrounding config made the tunneled v6 less attractive than the local network's native path.
That is an important correction to the usual blog-post advice. A dual-stack tunnel is not finished when the interface has a v6 address. It is finished when the host's default routes, resolver behavior, and destination selection all make the tunneled path the one traffic actually takes. If you do not verify that, you can end up with the worst kind of broken setup: one that looks modern in screenshots and still leaks in practice.
2. Disable IPv6 explicitly
If the VPN or surrounding stack is IPv4-only, the emergency workaround is also the honest one: disable IPv6 instead of pretending it will behave.
The kernel docs expose disable_ipv6, and the IETF leakage draft explicitly treats disabling IPv6 as the simple mitigation when proper IPv6 handling is unavailable.
A clean Linux disable looks like:
# /etc/sysctl.d/99-disable-ipv6.conf
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
Apply and verify:
sudo sysctl -p /etc/sysctl.d/99-disable-ipv6.conf
cat /proc/sys/net/ipv6/conf/all/disable_ipv6
ip -6 addr
ip -6 route
This is not elegant. It is operationally honest.
What not to do
Do not accept any of these states as "good enough":
- IPv6 enabled, but you assume the VPN probably catches it
- IPv6 disabled in one GUI, but still present at the kernel or interface level
- tunnel config claims "full tunnel" but only covers IPv4
- leak testing done once, then never repeated after network changes
That is how teams end up arguing about whether an issue is "really" a leak while the host is clearly taking native IPv6 routes outside the tunnel.
Verification is part of the fix
Every IPv6 mitigation needs verification. Not once. Repeatedly.
Check the host:
ip -6 addr
ip -6 route
Check the tunnel config.
Check after:
- connecting the VPN
- changing Wi-Fi
- resuming from sleep
- changing the router
- updating the VPN client
If you only test once on a calm home network and never again on hotel, office, tethered, or airport Wi-Fi, you have not really tested leak resistance. You have tested a single friendly moment.
This is also where /blog/webrtc-ip-leak-fix becomes relevant. A clean IPv4 story plus a sloppy IPv6 story produces confusing results in browser leak tests, and people often misdiagnose the symptom.
Likewise, if you move to encrypted DNS, keep it consistent. A dual-stack host with split resolver behavior is how you get the worst parts of both worlds, which is why this topic pairs with /blog/doh-vs-dot-leak-comparison.
The operator opinion
The industry has spent too long treating IPv6 as either a future problem or a checkbox problem.
It is neither.
If your VPN architecture does not account for IPv6, then your privacy architecture does not account for the network you are actually on. That is the hard truth underneath every "IPv6 leak prevention" article worth reading.
So keep the decision rule simple:
- if the tunnel can carry IPv6 correctly, carry it deliberately
- if it cannot, disable IPv6 explicitly and verify that it stayed off
What you should not keep is the fantasy that dual-stack hosts will quietly suppress one address family out of respect for your incomplete tunnel design.
They will not.
And if you are self-hosting WireGuard or another tunnel stack, fix this at the design level the same way you would fix firewall policy or DNS policy. IPv6 is not cleanup work. It is part of the network.