The tunnel is up, IPv4 sites load, and one hostname times out. The immediate conclusion is that the VPN is broken or the credentials are wrong, and neither is usually true. The name returned both an IPv4 and an IPv6 address, the application picked one, and only one of those candidates had a working path. The client made a selection decision; the tunnel simply did not cover what it selected.

Selection is not a coverage promise

Default address selection, described in RFC 6724, decides which source and destination pair a host prefers when several are available. Happy Eyeballs adds a connection strategy on top: it starts attempts on both families and keeps whichever answers first, so a user does not wait for a broken family to time out.

Neither mechanism creates a route. If your tunnel carries IPv4 only, an AAAA candidate is still a legitimate destination that the client may try, and the failure shows up as a slow load rather than an error, because the browser fell back. The user reports a slow site, not a broken one, and the support ticket inherits that vagueness. Reproduce it with a fixed family and the report becomes specific.

That fallback is why the symptom is inconsistent across applications. A browser hides the delay; a command-line client with a fixed family shows you the real failure immediately.

Find the family the request actually used

Start with the name, not the tunnel. Query both record types and note what came back:

dig +short A example.com
dig +short AAAA example.com
curl -4 -sS -o /dev/null -w '%{http_code}\n' https://example.com
curl -6 -sS -o /dev/null -w '%{http_code}\n' https://example.com

If the v4 request succeeds and the v6 request fails, you have reproduced the problem in a form you can debug. If both succeed from the shell and the browser still fails, look at the application's own resolver or a cached answer before touching the tunnel.

Keep the family and the destination in your notes. A ticket that says the site does not load over the VPN cannot be checked by anyone, while a ticket that says AAAA fails and A works points at a specific route.

Check the route for that family

For the failing family, ask the kernel which path it would use and compare it with the tunnel's configured addresses. On Linux, ip -6 route get for the destination shows the interface and source that would be selected.

Then check the tunnel itself. WireGuard peers carry an allowed-IPs list, and an entry for 0.0.0.0/0 says nothing about IPv6. If the peer's list has no IPv6 prefix, the client has no reason to send AAAA traffic into the tunnel, and the packet leaves through whatever the host would otherwise do.

Firewall rules and NAT policy deserve the same check per family. A rule written for IPv4 does not cover IPv6 on any platform, and this is the single most common reason one family works while the other does not.

Do not disable IPv6 to make the screenshot simple

Turning IPv6 off system-wide will make the symptom disappear and leave you without a diagnosis. It also breaks any destination that is IPv6-only, and it hides the same bug for the next application. If a machine genuinely should not use IPv6, that is a deliberate policy with an owner and a test. Turning it off during an incident is neither.

Decide what the client should do with the family and configure that explicitly: carry it through the tunnel, or block it in a supported way so the selection never offers an unreachable candidate. Both are legitimate designs. A global disable is neither, because it is not a design at all.

What to put in the ticket

Record four things: the hostname, the family that failed, the route the kernel chose, and the result of a family-specific request. That set is enough for someone else to reproduce the failure without guessing which of the two paths you meant.

The RFC 6724 address selection rules explain why the client preferred the candidate it did, and RFC 8305 explains the racing behaviour that hid the delay. Neither of them will route a packet for you, which is the part the tunnel has to do.

সম্পৰ্কিত প্ৰবন্ধ