---
title: "IPv6 Proxy Not Working on Dual-Stack: Why IPv4 and IPv6 Exits Differ"
description: "IPv6 proxy not working? Often the proxy captures only IPv4 while IPv6 goes direct. Learn the causes, how to confirm with /ip and curl -4/-6, and four fixes."
url: https://cdnping.org/en/blog/ipv6-dual-stack-proxy-mismatch
language: en
published: 2026-10-17
category: "Troubleshooting"
tags: ["IPv6","dual-stack","proxy","network troubleshooting","Happy Eyeballs"]
source: cdnping.org
license: Free to quote and summarize with a link to the url above.
---
# IPv6 Proxy Not Working on Dual-Stack: Why IPv4 and IPv6 Exits Differ

When a network has both IPv4 and IPv6 (dual-stack), the common complaint that "the IPv6 proxy isn't working" usually means the proxy client only captures IPv4. When you visit a site that supports IPv6, the system prefers IPv6 and connects directly, so the traffic never enters the proxy. To confirm, compare the exit addresses for IPv4 and IPv6. To fix it, either make the proxy client capture IPv6 as well, or make the machine use IPv6 less or not at all. The sections below cover causes, confirmation, and fixes in that order.

## Why a proxy can "fail" on a dual-stack network

### Happy Eyeballs: the OS prefers IPv6 by default

When a modern OS or browser connects to a domain, it queries both A (IPv4) and AAAA (IPv6) records. Under the Happy Eyeballs algorithm (RFC 8305, which succeeds RFC 6555), the client tries IPv6 first and falls back to IPv4 only if the IPv6 connection isn't established within a very short time (RFC 8305 suggests a default of about 250 milliseconds).

So as long as the machine has a working IPv6 address and default route, and the target site has an AAAA record, most connections go over IPv6. Many home broadband and mobile networks in China already hand out IPv6 addresses by default, so plenty of machines have been dual-stack all along without anyone noticing.

### Which proxy capture methods miss IPv6

Whether a proxy is affected depends on the layer at which it captures traffic.

| Capture method | Behavior on dual-stack | Reason |
|---|---|---|
| System proxy / in-app HTTP or SOCKS5 proxy | Usually unaffected | The app hands the domain name to the proxy, which resolves and connects on its side; the local machine never opens an IPv6 connection |
| Programs that ignore the system proxy (some CLI tools, SDKs) | Bypass the proxy entirely; both IPv4 and IPv6 go direct | The program never uses the proxy at all. This has nothing to do with IPv6, but it is often misdiagnosed as an IPv6 problem |
| TUN / virtual NIC mode with only IPv4 routes configured | IPv4 goes through the proxy, IPv6 goes direct | The virtual NIC only takes over 0.0.0.0/0, and the IPv6 default route still points at the physical NIC |
| Proxy client's DNS lets AAAA records through | Some sites connect directly over IPv6 | Real IPv6 addresses are resolved, and neither the rules nor the routes cover IPv6 |
| Gateway / soft-router transparent proxy handles only IPv4 | Every device on the LAN may connect directly over IPv6 | Firewall rules were written only for iptables, with no ip6tables or equivalent nftables rules |

The most common symptom: you open an IPv6-capable site in the browser and the region shown doesn't match your proxy node. An IPv4-only site looks fine. Reload the same page a few times and the result flips back and forth. That last case is Happy Eyeballs at work: when IPv6 is occasionally a bit slow, the connection falls back to IPv4.

There is also a case that isn't a fault: the same machine uses different exits for different services. If you need a stable exit (for example, to debug regional API routing or compare latency), this makes your measurements impossible to reproduce.

## How to confirm IPv6 is bypassing the proxy

### In the browser: compare IPv4, IPv6, and multiple exits on /ip

Open cdnping's [IP and environment check](/en/ip) and look at three things:

1. **IPv4 / IPv6 detection**: The page reports the exit for IPv4 and IPv6 separately. If their geolocation and ASN differ clearly (for example, IPv4 shows a datacenter range where your proxy node is, while IPv6 shows your local ISP), the proxy is almost certainly capturing only IPv4.
2. **Multi-exit detection**: The page reads the Cloudflare trace from sites such as Claude, ChatGPT, and Grok to show which exit is actually used for each. If some sites show the proxy exit and others show your local exit, traffic is splitting across different paths.
3. **Mainland China split-routing check and DNS leak**: Split-routing rules and DNS configuration can also cause mismatched exits, so you can rule them out at the same time. For how DNS leaks work and how to judge them, see [DNS leaks and WebRTC leaks](/en/learn/dns-leak-webrtc-leak).

If you need to send the results to a colleague or paste them into an issue, /ip can generate a watermarked result image. Turn on Hide IP before generating it and your exit address won't appear in the image. The browser fingerprint shown on the page is computed locally and is not uploaded.

### In the terminal: compare exits with curl -4 / -6

Programs outside the browser (CLI tools, SDKs, IDE plugins) don't necessarily take the same path as the browser, so test them separately in a terminal. Cloudflare's trace endpoint returns the client IP it sees, which makes it a good reference:

```bash
# Force IPv4
curl -4 -s https://www.cloudflare.com/cdn-cgi/trace | grep -E '^(ip|loc|colo)='

# Force IPv6
curl -6 -s https://www.cloudflare.com/cdn-cgi/trace | grep -E '^(ip|loc|colo)='

# No flag: see which one the system picks by default
curl -s https://www.cloudflare.com/cdn-cgi/trace | grep -E '^(ip|loc|colo)='
```

How to read the results:

| Observation | Conclusion |
|---|---|
| `-6` fails with "Couldn't connect" or no route | The machine has no working IPv6, so the problem is elsewhere |
| `-4` shows the proxy exit, `-6` shows your local ISP address | The proxy captures only IPv4. This is the case this article is about |
| `-4` and `-6` both show local addresses | That program isn't using the proxy. First check the `HTTP_PROXY`, `HTTPS_PROXY`, and `ALL_PROXY` environment variables, or switch to TUN mode |
| `-4` and `-6` both show the proxy exit, in the same region | Both stacks are captured; look at split-routing rules or DNS for the mismatch |
| `ip=` without any flag is an IPv6 address | The default connection used IPv6, consistent with Happy Eyeballs behavior |

Two more commands for checking the local state:

```bash
# Linux: is there a global IPv6 address and an IPv6 default route
ip -6 addr show scope global
ip -6 route show default

# macOS: show IPv6 addresses on each interface and the IPv6 routing table
ifconfig | grep inet6
netstat -rn -f inet6 | head -20
```

On Windows, run `Get-NetIPAddress -AddressFamily IPv6` and `Get-NetRoute -AddressFamily IPv6 -DestinationPrefix ::/0` in PowerShell.

If you are debugging a program that calls an AI API, replace the trace URL above with the target API's domain and run `curl -4 -o /dev/null -w '%{remote_ip} %{time_connect}\n'` once with `-4` and once with `-6`, to see the address actually connected and the connection time. AGI Plan is a commercial partner of cdnping. If you use AGI Plan, you can run the same comparison against `agiplan.dev`, then check the AGI Plan availability that cdnping mirrors at [/status/agiplan](/en/status/agiplan).

## How to fix it: four options and their trade-offs

Once you've confirmed the proxy only captures IPv4, consider the options in the order below. Changing the proxy client usually has the smallest blast radius; changing the OS or the gateway affects progressively more.

### Option 1: Enable IPv6 support in the proxy client

Most clients that support TUN mode have an IPv6-related switch, usually named "IPv6" or "Enable IPv6 routing", or an IPv6 address range you add to the virtual NIC in the config file. Once enabled, the virtual NIC also takes over `::/0`, and IPv6 traffic enters the proxy.

- Pros: The local network stays intact, domestic sites you connect to directly can still use IPv6, and other devices on the LAN are unaffected.
- Prerequisite: The proxy chain itself must be able to handle IPv6 targets. If the remote end doesn't support IPv6, the usual approach is to have the client's DNS return only A records (many clients have a "disable AAAA" or "IPv4-only resolution" option), so apps only open IPv4 connections.
- Note: After enabling it, rerun the `curl -6` comparison above to confirm the IPv6 exit actually changed.

### Option 2: Make the system prefer IPv4

Leave IPv6 on and only change the address selection priority. When a domain has both A and AAAA records, the system will try IPv4 first.

```bash
# Linux (glibc): add one line to /etc/gai.conf
precedence ::ffff:0:0/96  100
```

On Windows you can change the prefix policy, for example by running `netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 60 4` as administrator. macOS has no equally simple system-level switch.

- Pros: A small change, and IPv6 remains usable.
- Limitations: It only affects programs that use the system resolver. Browsers with built-in DNS-over-HTTPS and programs that ship their own resolver may not honor it. Sites with only AAAA records will still connect directly over IPv6.

### Option 3: Disable IPv6 system-wide

This has the most certain effect and the biggest side effects.

```bash
# Linux: disable temporarily (restored after reboot)
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1

# macOS: turn off IPv6 on the Wi-Fi interface (use the service name from networksetup -listallnetworkservices)
sudo networksetup -setv6off Wi-Fi
# Restore
sudo networksetup -setv6automatic Wi-Fi
```

On Windows, you can uncheck "Internet Protocol Version 6 (TCP/IPv6)" in the adapter properties, or use `Disable-NetAdapterBinding -Name "Ethernet" -ComponentID ms_tcpip6` in PowerShell.

- Pros: There is no longer any chance of direct IPv6 connections, so exit behavior is the easiest to predict.
- Cost: You lose the direct paths IPv6 provides. Some domestic Chinese services and ISP networks may perform better over IPv6. Some system components depend on IPv6 loopback or link-local addresses, so disabling it globally can cause hard-to-trace problems. Microsoft's official documentation also advises against disabling IPv6 entirely and recommends using prefix policy to prefer IPv4.
- Recommendation: Verify with the temporary method first, and decide whether to make it permanent only after the problem is confirmed fixed.

### Option 4: Handle it on the gateway or soft router

If every device on the LAN is affected, the cause is most likely that the gateway's transparent proxy only has IPv4 rules. You can add the matching IPv6 forwarding rules on the gateway, or stop handing out IPv6 from the gateway (no RA, no DHCPv6). The latter is the same as applying Option 3 to the whole LAN, with the same trade-offs.

### The four options compared

| Option | Scope | Keeps IPv6? | Best for |
|---|---|---|---|
| Enable IPv6 in the client | This machine | Yes | Client and remote end both support IPv6 |
| Prefer IPv4 in the OS | This machine, system resolver only | Yes | You want minimal changes and quick mitigation first |
| Disable system IPv6 | This machine | No | You need a fully predictable exit |
| Handle on the gateway | Entire LAN | Depends on approach | Multiple devices have the problem at once |

These options exist only to make the machine's network behavior match your configuration, for easier troubleshooting and measurement. They are not about bypassing any service's regional restrictions. When using overseas services, follow their terms of service and local laws and regulations.

## Checklist after the change

- [ ] The `curl -4` and `curl -6` trace results match what you expect (identical, or `-6` is no longer available)
- [ ] The exit of plain `curl` with no flag matches the browser
- [ ] The IPv4 / IPv6 cards and multi-exit detection on [/ip](/en/ip) no longer diverge
- [ ] The DNS leak test result matches what you expect
- [ ] Run a test on the [home page speed test](/en/) and compare each API's "first connection" time before and after the change, to confirm you haven't added latency

If the exits now match but a particular AI service still won't load, the problem may not be your local network. Check [/down](/en/down) to see whether other users are reporting the service as down, or look at [/status](/en/status) for cdnping's probe results from the Cloudflare edge, run every 5 minutes, then decide whether to keep troubleshooting locally or wait for the service to recover. For related concepts, continue with [What is split tunneling](/en/learn/split-tunneling).
