Blog

IPv6 leak: how it happens and how to test

An IPv6 leak is IPv6 traffic that skips the tunnel. How it happens, how to test for one, and what our own phone run showed with the tunnel down and up.

Published October 16, 2026 · 10 minutes read

Key takeaways

  • A route-table mismatch causes an IPv6 leak: the device has an IPv6 route outside the tunnel while the tunnel carries only IPv4.
  • Our phone run had 4 states; in both tunnel-up states the IPv6 default route sat on the tunnel interface, and the app stayed on Connecting.
  • The interface a route lookup names for a public IPv6 address decides the outcome: if it is the tunnel, IPv6 is in the tunnel; if it is Wi-Fi or Ethernet, it is not.
  • Carrying, refusing or disabling IPv6 each fix a leak, at a different cost.
On this page (8)

An IPv6 leak is IPv6 traffic that leaves your device by the ordinary network instead of the VPN tunnel. It needs only two things: an IPv6 route outside the tunnel, and a tunnel that carries IPv4 and nothing else.

Most pages on this topic stop at "disable IPv6". This one shows the route table behind the problem, then what our own phone run recorded with the tunnel down and up, including the parts the run could not reach.

What is an IPv6 leak, and how does it happen with a VPN connected?

A leak happens when the device sends a packet over IPv6 and the route for it points at the physical interface. IPv6 is the newer address family, defined in RFC 8200. A dual-stack device holds both an IPv4 and an IPv6 address on the same network.

The tunnel decides which traffic it takes by its routes. A WireGuard-style tunnel takes the destinations listed in AllowedIPs, the setting that names which addresses the tunnel carries.

  • ::/0 covers all of IPv6, so that entry sends every IPv6 destination into the tunnel.
  • 0.0.0.0/0 alone leaves IPv6 outside the tunnel. If the physical network still hands the device an IPv6 default route, v6 connections go straight out.

So the fault is rarely the test page, and rarely "the VPN failing". It is a route table with one row too few.

Why does a device pick IPv6 over IPv4 at all?

Because its default address-selection policy ranks IPv6 destinations above IPv4 ones. RFC 6724 defines that policy, and it sorts a destination last when the device has no usable route or source address for it.

Take a site that publishes both an A record (an IPv4 address) and an AAAA record (an IPv6 address) for its name. The device gets both and sorts them. The policy tries IPv6 first when it holds a usable IPv6 source address. That sort is the reason a leak can exist while IPv4 looks perfectly protected.

The rule that saves you is the same one. With no IPv6 default route and no on-link IPv6 prefix covering the destination, the destination is not usable. It sorts last and the device falls back to IPv4. No route means nothing can leave over IPv6. On the Wi-Fi side, that is what our phone run below shows in every state.

A device can hold three kinds of IPv6 address:

  • Link-local addresses (fe80::/64), which never leave the local link.
  • Unique local addresses, from a private prefix.
  • Global addresses, from the network.

RFC 4941 adds temporary addresses that change over time, so the address a site sees can differ from the stable one you may have noted. RFC 4941 has since been replaced by RFC 8981. Addressing rules are in RFC 4291.

Where does the IPv6 default route go when an Android VPN connects?

In our run on one Android phone, the ForestVPN client put the IPv6 default route on the tunnel interface. The Wi-Fi network offered no IPv6 default route of its own, so a leak could not occur there. The run also showed what we could not test, and that list is long.

How this was tested

Product
ForestVPN for Android 4.0.23 (release candidate)
Version
4.0.23, Free tier, Amsterdam exit, Quantum protocol
System
Android 15 on a moto g54 5G
Checked
Runs
1
Not tested

One run on one phone on its own Wi-Fi network, taken on 2026-10-16 between about 09:44 and 09:50 UTC. Over adb we read the device's IPv6 addresses, its IPv6 routes in every routing table, and the result of two ping6 probes (2 packets each) to an off-link private address and to a public IPv6 literal. No website was opened; one public IPv6 address was pinged; no account number, session or exit address was read or kept, and LAN and tunnel addresses are redacted. Not tested: the Working state (the verdict that means data flows both ways; the app stayed on Connecting, showing "Checking both ways"), the kill switch, a Linux client, a dual-stack provider network, a test page, DNS AAAA behaviour and any IPv6 data through the tunnel. This is one phone on one lab network on one day.

StateIPv6 on Wi-FiIPv6 on tunnel interfaceIPv6 default routePing to off-link private addressPing to public literal
1 Tunnel downPrivate LAN addresses (one temporary, one stable) and link-local; no global addressNoneNone on Wi-FiNetwork is unreachableNetwork is unreachable
2 Tunnel up, about 20 sUnchangedOne private /128 address and link-local, MTU 1280Tunnel interfaceNetwork is unreachable2 sent, 0 received
3 Tunnel up, about 65 sUnchangedSameTunnel interfaceNetwork is unreachable2 sent, 0 received
4 App stoppedUnchangedGoneNoneNetwork is unreachableNetwork is unreachable
Where the IPv6 default route pointed in each state of the phone run. The same values are in the table above.

Three readings follow. No more than that.

The route went to the tunnel

In states 2 and 3 the ::/0 route went to the tunnel interface, not to Wi-Fi. That is the client carrying IPv6 toward the tunnel rather than leaving the table for the physical network to fill. The Wi-Fi network never offered a default route of its own, so even a table with a gap would have had nothing to send traffic through.

The silent ping proves nothing

The ping to the public literal got no answer, and that proves nothing about the tunnel. The app never showed Working, the connection verdict for data flowing both ways, so a silent v6 probe is what an unfinished connection looks like. The Connecting stall was seen on this lab phone on this day, and we do not guess a cause.

In state 1 the probe failed differently, with "Network is unreachable", because the device had no usable IPv6 default route.

The lab network was private only

On this run, Wi-Fi held only private addresses. A real provider network is the case that matters for leaks, and we did not run it. There a router advertisement (the message a router sends to tell devices their IPv6 prefix and default route) hands the device both. If you want the Working verdict explained, see how connection status is computed.

How do I test for an IPv6 leak myself?

List what the device holds with the tunnel down, connect, wait for Working, and list it again. Two lists and one page are enough; the aim is to see which interface the system picks for a public IPv6 address while the tunnel is up.

  1. With the VPN off, list your IPv6 addresses. On Linux and Android's shell run ip -6 addr; on Windows run ipconfig; on macOS use Network settings or ifconfig. Note whether any address is global, meaning not private and not link-local. An address starting with fd is private even when the output says scope global.
  2. Ask which interface reaches a public IPv6 address. On Linux and in Android's shell run ip -6 route get 2001:4860:4860::8888; on macOS run route -n get -inet6 2001:4860:4860::8888; in Windows PowerShell run Find-NetRoute -RemoteIPAddress 2001:4860:4860::8888. Use this instead of looking for a default row: a client that routes through policy rules or its own table never shows one on the main table. The interface the lookup names is the answer. An error such as "Network is unreachable" means the device has no IPv6 route to it.
  3. Connect and wait for the Working verdict. Read the same two lists again.
  4. Compare. If the lookup now names the tunnel interface, IPv6 is being routed into the tunnel. If it still names Wi-Fi or Ethernet, IPv6 is not routed into the tunnel, and you have the mismatch from the first section.
  5. Open an IPv6 test page such as test-ipv6.com in a new tab and read which address family it says your connection used. Then try a probe from the shell, for example ping -6 2001:4860:4860::8888 on Linux and Windows, or ping6 on macOS. A reply means a working IPv6 path, and the route lookup tells you which interface carried it. Silence means only that nothing answered, which is not a leak finding.

Step 5 can mislead, and the next section says why.

Name lookups and browser addresses leak by other routes: see the DNS leak test and the WebRTC leak guide.

What does an IPv6 test page actually show?

It shows the address family of the connection between your browser and the page, and usually the address that connection came from. It does not rate the VPN, and it does not see traffic that never touched the page.

That distinction matters in both directions. A page that prints only an IPv4 address does not prove the device has no IPv6. The page may have been reached over IPv4 because a record or a path was missing. A page that prints an IPv6 address from your own network while the tunnel shows Working is a clear mismatch, because it names the physical network and not the tunnel.

Read the test page together with the route lookup from the previous section, never in place of it. The route table says what the device will do; the page says what one site saw once. Both are single observations.

The IP address, DNS and WebRTC checks are separate tests that this page does not repeat. A leaking resolver is its own failure.

Should I disable IPv6 to stop a leak?

Disabling IPv6 closes the gap but also removes IPv6 everywhere, so treat it as the blunt option and pick it last. Three fixes exist, and each costs something different.

FixWhat it doesWhat it costs
Carry IPv6 through the tunnelAdds ::/0 to AllowedIPs and gives the tunnel an IPv6 address, so v6 connections go to the exitThe exit must carry IPv6. With none, v6 sites fall back to IPv4 quickly if the refusal is immediate, and stall if it is not
Refuse IPv6 while protection is onA firewall rule rejects outgoing (or, on a router, forwarded) IPv6, so devices use IPv4IPv6-only destinations fail while protection is on
Disable IPv6 on the adapterThe device has no IPv6 address, so nothing can leave over itIPv6 is gone on every network, until you turn it back on

Carrying v6 is the cleanest fix, and it asks the most of the exit. Refusing it is quick and honest about what it does. Disabling is what people reach for first because every guide says so. It works, but you have to remember to undo it.

A kill switch, a rule that blocks traffic when the tunnel is not carrying it, belongs next to any of these as a second layer. It is never absolute: it covers the cases it was built for, and the kill switch page says which.

How do I stop an IPv6 leak on a router?

On a router the question is who owns the IPv6 default route, and your rules decide that, not the app.

MikroTik

Our MikroTik recipes are IPv4 only. Choosing what goes through the tunnel says that if the router has working IPv6, selected destinations are also reachable over v6, around the tunnel. It gives two RouterOS commands that show whether the router advertises itself as an IPv6 router and has a default route for it. The MikroTik kill switch recipe states the same limit.

OpenWrt

OpenWrt is different:

  • With the nftables firewall, IPv6 from protected devices goes into the tunnel when the tunnel has an IPv6 address, and is refused when it has none.
  • With the older fw3 firewall on 21.02, forwarded LAN IPv6 is refused while protection is on.

The OpenWrt kill switch page has the detail and its verification status, which is a lab run and not yet hardware.

For a device on a home network behind a router, compare OpenWrt and MikroTik before you pick where the rules should live.

What if my VPN is connected and nothing loads over IPv6?

That is the opposite fault: IPv6 is routed into a tunnel that cannot deliver it, and the device waits. Our run cannot show it, because the tunnel there was not carrying any data yet.

Check the verdict first. If the app does not show Working, the tunnel is not carrying data in both directions, and nothing about IPv6 can be read from it. VPN connected but no internet covers that case, and the degraded-connection page says what the verdict means and what to try.

Questions and answers

What is an IPv6 leak?

Traffic sent over IPv6 that leaves the device by the physical network instead of the tunnel. It happens when the tunnel handles IPv4 only and the device still has an IPv6 address and an IPv6 route outside it.

How do I test for an IPv6 leak?

List the device's IPv6 addresses, then ask the system which interface it would use to reach a public IPv6 address, with the tunnel down and again once the tunnel is up and data flows both ways. If the lookup names Wi-Fi or Ethernet while the tunnel is up, IPv6 is leaving outside the tunnel. An IPv6 test page is a second, single observation.

Should I disable IPv6 to stop a leak?

It closes the gap, because a device with no IPv6 address sends nothing over IPv6. The cost is that you lose IPv6 on every network, and sites reachable only over IPv6 stop loading. Carrying IPv6 through the tunnel, or refusing it while protection is on, are the alternatives.

Can IPv6 reveal my location?

An IPv6 address comes from the network you are on, so a site that sees it learns which network the connection came from, as it does with an IPv4 address. Whether that address is unique to your device depends on the network and on temporary addresses.

What does an IPv6 test page show?

The address family the page's own connection used and, on most pages, the address. A page that shows only an IPv4 address does not prove the device has no IPv6; it may mean the page was reached over IPv4 because a path or a record was missing.

How does ForestVPN handle IPv6?

In our one phone run on 2026-10-16 the client put an IPv6 address and an IPv6 default route on the tunnel interface. We did not reach the Working verdict in that run, so we make no claim about IPv6 traffic through the tunnel.

Sources

  1. RFC 8200: Internet Protocol, Version 6 (IPv6) Specification (read October 16, 2026)
  2. RFC 6724: Default Address Selection for IPv6 (read October 16, 2026)
  3. RFC 4941: Privacy Extensions for Stateless Address Autoconfiguration in IPv6 (read October 16, 2026)
  4. RFC 8981: Temporary Address Extensions for Stateless Address Autoconfiguration in IPv6 (read October 16, 2026)
  5. RFC 4291: IP Version 6 Addressing Architecture (read October 16, 2026)
  6. WireGuard: cryptokey routing (read October 16, 2026)
  7. test-ipv6.com (read October 16, 2026)

How this was made

Drafted with AI assistance from standards and a lab run on one Android phone, then checked by automated gates and an editor.

All posts

Back to top

Ask us anything