IPv4 vs IPv6: why sites show a different address

Why one site shows your IPv6 address and another your IPv4 one, how devices choose between them, NAT64 on mobile networks, and how to check IPv6 works.

Visit two sites and one may show 2001:db8:1234::5 while the other shows 203.0.113.7. Both are your public addresses. Most home and mobile connections now have one of each, a setup called dual stack, and every connection uses one or the other. This guide explains how your device picks, why the pick can change from visit to visit, what IPv6-only mobile networks do, and how to check that IPv6 really works.

Two addresses, one per connection

A site that has only an IPv4 address (only an A record in DNS) always sees your IPv4 address. A site with both an A and an AAAA record can be reached either way, and your device chooses. That is why an older site and a newer one disagree about "your IP": each shows the one your device used for it.

Neither address is more "real". Your IPv4 address is usually shared by every device behind your router, and sometimes with other customers too; your IPv6 address is usually your device's own, and often a temporary one that changes daily. The public vs private IP guide explains both.

How your device chooses

Two standards decide:

  • Default address selection (RFC 6724): its default policy table ranks IPv6 (::/0, precedence 40) above IPv4 (::ffff:0:0/96, precedence 35), so by default a global IPv6 address is tried before an IPv4 one. The RFC's other rules and the system's own policy can change the order, for example for some special-purpose IPv6 addresses.
  • Happy Eyeballs (RFC 8305): the browser asks DNS for both records. If the IPv4 answer comes first, it waits up to 50 milliseconds for the IPv6 one, so that IPv6 usually gets its preference; if the IPv6 answer is later than that, it can start with IPv4. When it does start with IPv6 and that connection hasn't succeeded within a short delay, 250 milliseconds by the RFC's recommendation, it starts an IPv4 attempt in parallel and uses whichever connects first.

The result: on a healthy dual-stack connection sites usually see your IPv6 address, and when the IPv6 path or its DNS answer is slow, or the path is broken, your browser quietly falls back to IPv4 instead of failing. So one site can see your IPv6 address on one visit and your IPv4 address on the next, without anything changing on your side that you'd notice.

What this changes for site owners

  • A visitor can come from two unrelated addresses within minutes. Sessions, rate limits and fraud rules keyed on the IP address should expect it.
  • An allow-list that holds only a customer's IPv4 address breaks the day their network enables IPv6. Ask for both, or for their IPv6 prefix, because the address part of IPv6 changes.
  • A location lookup of the IPv4 and the IPv6 address can differ, since they come from different blocks, sometimes from different parts of a provider's network.

To see the visitor's address correctly behind a proxy or CDN, see the client IP guide.

IPv6-only mobile networks: NAT64

Some mobile networks give phones IPv6 only and translate to IPv4 at the edge of their network:

  • NAT64 (RFC 6146) translates IPv6 packets to IPv4, and DNS64 answers an IPv4-only name with a made-up IPv6 address that leads to the translator. These addresses typically use the well-known prefix 64:ff9b::/96 (RFC 6052): 64:ff9b::192.0.2.33 stands for 192.0.2.33.
  • 464XLAT (RFC 6877) adds a translator on the phone, so apps that only speak IPv4 still work.

On such a network, an IPv6-capable site sees your phone's IPv6 address, while an IPv4-only site sees an IPv4 address of the operator's NAT64, shared with many other customers. A device can detect DNS64 by asking for the IPv6 address of ipv4only.arpa, a name that has only IPv4 addresses (192.0.0.170 and 192.0.0.171); getting an answer means DNS64 synthesized it (RFC 7050):

dig +short AAAA ipv4only.arpa     # empty on most networks; 64:ff9b::c000:aa and similar behind DNS64

How to check that IPv6 works

The quickest check is the IPv6 test, which shows both addresses and which one your browser used. From a terminal:

curl -6 -sS --fail-with-body --max-time 5 https://host.sh/ip || echo "the IPv6 request failed"
curl -4 -sS --fail-with-body --max-time 5 https://host.sh/ip || echo "the IPv4 request failed"

If the -6 command fails while the -4 one works, IPv6 is probably not working on your connection, though one failed request can also be a problem with that one site or its DNS. An HTTP error (curl prints the error page and says The requested URL returned error) means the request got through over that family, so it isn't a broken path; a timeout or Couldn't connect points at the path. These clues tell you more:

ip -6 addr show scope global    # Linux: look for an address starting with 2 or 3 (fd.. is only local)
ip -6 route show default        # Linux: whether IPv6 traffic has a way out of your network
ifconfig | grep inet6           # macOS
ipconfig                        # Windows: an IPv6 address that doesn't start with fe80 or fd

Public IPv6 addresses come from 2000::/3, so they start with 2 or 3 (IANA IPv6 address space). No such address usually means your router or provider doesn't offer IPv6, or it's switched off in the router. An address without a working route, or a test that sometimes falls back to IPv4, points at a broken IPv6 path: worth reporting to your provider, because Happy Eyeballs hides it rather than fixing it.

FAQ

Why does one website show my IPv6 address and another my IPv4 address?

Your connection has both. Sites with IPv6 usually see your IPv6 address, because devices prefer IPv6 by default when it works; sites with only IPv4 see your IPv4 address. Both are your public addresses.

Why did my IP address switch from IPv6 to IPv4 on the same site?

Browsers usually try IPv6 first and fall back to IPv4 within a fraction of a second if IPv6 is slow or fails, and they can start with IPv4 when the IPv6 DNS answer is late (Happy Eyeballs, RFC 8305). A flaky IPv6 path makes the same site see either address from one visit to the next.

What is a 64:ff9b:: address?

An IPv6 address made up by DNS64 on an IPv6-only network, usually a mobile one. The last 32 bits are the IPv4 address of the site you are reaching, and the operator's NAT64 translates the traffic to IPv4.

How do I know if IPv6 works on my connection?

Open the IPv6 test, or run curl -6 https://host.sh/ip in a terminal. If it prints an IPv6 address, IPv6 works; if it fails while curl -4 works, IPv6 is probably not working on your connection.

This page as Markdown: /guides/ipv4-vs-ipv6/index.md