Verified: 2026-10-17By Alex Chen (Lead BGP Architect)RFC 8305 & Happy Eyeballs9 Min Read

Why Client-Side IP Lookups Require Dual-Stack Probing

An architectural analysis of modern dual-stack Internet connectivity, examining how browser connection algorithms mask network paths and why decoupled endpoints are essential for diagnostic accuracy.

Quick Answer

A single HTTP request cannot diagnose a dual-stack connection because modern browsers use the Happy Eyeballs v2 algorithm (RFC 8305), which gives IPv6 an aggressive head start and terminates the race as soon as one protocol connects. To accurately detect both public IPv4 and IPv6 addresses, diagnostic tools must issue decoupled, parallel HTTP requests to dedicated IPv4-only (A-only) and IPv6-only (AAAA-only) endpoints.

  • Happy Eyeballs v2: RFC 8305 gives IPv6 a 250ms head start, masking IPv4 connectivity.
  • Endpoint Decoupling: Dedicated A-record and AAAA-record subdomains are required for discrete measurement.
  • Broken Dual-Stack Detection: Decoupled probes isolate silent IPv6 routing blackholes.

1. The Mechanics of Happy Eyeballs v2 (RFC 8305)

Before Happy Eyeballs was standardized, if a user had a misconfigured or broken IPv6 gateway, connections would hang for up to 30 seconds before timing out and falling back to IPv4.

RFC 8305 solved this by engineering an asynchronous client-side race condition:

1. Concurrent DNS Resolution:Browser queries A and AAAA records in parallel.
2. IPv6 Preferential Head Start:Sends TCP SYN to IPv6 address; starts 250ms timer.
3. IPv4 Fallback Dispatch:If no SYN-ACK after 250ms, dispatches TCP SYN to IPv4 address.
4. Socket Commitment:First connection to complete TLS handshake handles the HTTP request.

2. Comparison of Diagnostic Probing Architectures

Compare how different diagnostic designs evaluate client IP addresses:

Comparative Analysis of Dual-Stack Network Probing Designs
Probing MethodologyIPv4 VisibilityIPv6 VisibilityFailure IsolationOperational Complexity
Single Dual-Stack EndpointOnly if IPv6 fails completelyPreferred (100% when active)Zero (Cannot isolate which protocol broke)Lowest (Single domain)
Decoupled Parallel Probes100% Deterministic100% DeterministicComplete (Shows exact failing protocol)Moderate (Requires 2 dedicated DNS hosts)
Client WebRTC Candidate ScanLocal LAN IP / mDNSLocal Link-Local / SLAACPartial (Subject to browser mDNS masking)High (Complex WebRTC handshake)
Sequential Fallback ProbeDelayed by timeoutAttempted firstSlow (User experiences 5-10s latency)Poor user experience

Dual-Stack Diagnostic Probing Decision Tree


                 [ Client Initiates Dual-Stack Diagnostic ]
                                     |
                       +-------------+-------------+
                       |                           |
            [ Single Dual-Stack Host ]   [ Decoupled Parallel Probing ]
              dual.example.com                 Recommended Standard
              (Has both A & AAAA)                  |
                       |                 +---------+---------+
            Happy Eyeballs Races         |                   |
            IPv6 wins -> IPv4 hidden  [ IPv4 Probe ]     [ IPv6 Probe ]
            Incomplete diagnostic     ipv4.example.com   ipv6.example.com
                       |              (Only A Record)    (Only AAAA Record)
                       |                 |                   |
                       +-------->        +---------+---------+
                                                   |
                                     [ Full Dual-Stack Matrix ]
                                     IPv4: Confirmed Public IP
                                     IPv6: Confirmed Public IP
                                     Health: Dual-Stack Operational

3. Production Client Implementation Pattern

To implement deterministic dual-stack detection in web applications, use Promise.allSettled across isolated endpoints:

Parallel Async Fetch Pattern:const [v4, v6] = await Promise.allSettled([fetch('https://ipv4.example.com/api/ip'), fetch('https://ipv6.example.com/api/ip')]);
Strict Timeout Controller:AbortSignal.timeout(3500) prevents stalled UI spinners on dead routes.

4. Practical Verification: Testing Protocols from Terminal

Force curl to use explicit IP versions to verify discrete protocol routing:

Force Explicit IPv4 Connection:curl -4 -s https://myipwiki.cc/api/ip
Force Explicit IPv6 Connection:curl -6 -s https://myipwiki.cc/api/ip
Observe Happy Eyeballs Race in Chrome:chrome://net-internals/#sockets

Frequently Asked Questions

Why does a regular IP lookup tool only show my IPv6 address and hide my IPv4?

Modern web browsers implement the Happy Eyeballs v2 algorithm (RFC 8305). When connecting to a dual-stack domain with both A and AAAA records, the browser intentionally gives IPv6 a 250ms head start. If IPv6 succeeds, the connection is established over IPv6, and the web server never sees your IPv4 address during that single HTTP transaction.

How does a true dual-stack test verify both protocols?

A true dual-stack testing tool must decouple the probes by maintaining two distinct subdomains: an IPv4-only host (configured with strictly A records) and an IPv6-only host (configured with strictly AAAA records). The client browser issues independent, parallel asynchronous fetch() requests to both endpoints.

What is the Happy Eyeballs "Connection Attempt Delay"?

Standardized in RFC 8305 Section 5, the recommended Connection Attempt Delay is 250 milliseconds. If the initial IPv6 TCP SYN handshake does not complete within this window, the browser fires an IPv4 TCP SYN. Whichever handshake finishes first establishes the socket, ensuring users experience no delay if IPv6 routes are broken or blackholed.

Can a browser test for IPv6 support without making an external HTTP request?

Browsers cannot directly query low-level network interface adapters due to security sandboxing. However, WebRTC APIs can generate local ICE candidates that inspect whether link-local or global IPv6 addresses are bound to local adapters, though modern privacy shields often mask these candidates behind mDNS hostnames.

Data & Technical Sources

  • IETF RFC 8305 — Happy Eyeballs Version 2: Better Connectivity Using Concurrency
  • IETF RFC 6555 — Happy Eyeballs: Success with Dual-Stack Hosts (Historic)
  • IETF RFC 8200 — Internet Protocol, Version 6 (IPv6) Specification