Explainer

Public vs private IP address: the difference and what a proxy changes

Public vs private IP address: which ranges are private, which address a website sees, the edge cases we tested, and which one belongs in an allowlist.

HProxy Team··Updated October 10, 2026·8 min read
HProxy.Explainer

Skip the dead lists.

Our free proxy list re-checks every exit every few minutes across 100+ countries, with a live last-checked time, so you copy IPs that worked moments ago, not a stale text dump.

Open the free proxy list→

A public IP address can be reached across the internet, and it is the address every website sees. A private IP address works only inside its own network, such as your home Wi-Fi, and many networks reuse the same ones. Your router translates between the two, and a proxy replaces the public one.

We checked 14 addresses on 10 October 2026 with Python's standard library and our own IP lookup. Three results are easy to get wrong. 172.32.0.1 is a public address of T-Mobile USA. 100.64.0.1 is neither private nor public. And Python counts documentation addresses as private.

Public vs private at a glance

Public IP addressPrivate IP address
Reachable fromThe whole internetOnly its own network
UniqueYes, one holder at a timeNo, many networks reuse the same ones
Handed out byYour provider or a hosting companyYour router or the network's admin
Seen by websitesYesNever
What a lookup findsCountry, network, providerNothing: our lookup answers 400 private_ip
Example on this page203.0.113.7 (a documentation stand-in)192.168.1.20

Which IP addresses are private?

RFC 1918, published in February 1996, reserves three blocks "for private internets":

BlockFirst to last addressAddresses
10.0.0.0/810.0.0.0 to 10.255.255.25516,777,216
172.16.0.0/12172.16.0.0 to 172.31.255.2551,048,576
192.168.0.0/16192.168.0.0 to 192.168.255.25565,536

The number after the slash is the prefix length. A /12 fixes the first 12 bits of the address and leaves 20 bits for hosts, so the block holds 2 to the power of 20 addresses. The same standard explains why they never cross the internet: "private addresses have no global meaning."

The middle block ends at 172.31.255.255, and the next address is public. Our lookup placed 172.32.0.1 with T-Mobile USA, network AS21928. So reading every 172 or 192 address as private is a mistake. In those ranges, only 172.16 to 172.31 and 192.168 are private.

Three of the six guides we read label the blocks class A, B and C. One gives the middle block "16 bits for the network". It has 12. RFC 1918 itself describes it in the old terms as "a set of 16 contiguous class B network numbers". The class system is legacy: RFC 4632 says equipment built on it "cannot be expected to work correctly" on the internet.

Addresses that are neither public nor private

Not every address outside those blocks is public. IANA keeps a registry of special-purpose addresses, last updated on 9 October 2025. It marks these as not globally reachable too:

  • 100.64.0.0/10, shared address space. Providers that run carrier-grade NAT number the link to your router with it. RFC 6598 calls it "distinct from RFC 1918 private address space", because it is meant for providers' networks. Our guide to CGNAT covers it in depth.
  • 169.254.0.0/16, link-local. Valid only on the local link. The registry marks it as not forwardable at all.
  • 127.0.0.0/8, loopback. The machine talking to itself.
  • 192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24, documentation. Reserved for examples, like the ones on this page.

IPv6 has its own private range. RFC 4193 defines unique local addresses in fc00::/7, in practice fd00::/8. They "are not expected to be routable on the global Internet." Link-local IPv6 addresses sit in fe80::/10 (RFC 4291).

How a private address reaches the internet

Your router does the translation, called NAT. RFC 3022 calls the usual form NAPT: many private addresses and their ports "are translated into a single network address and its TCP/UDP ports." That is why every device on your Wi-Fi shows websites the same public address.

The shortage behind this is old news. On 3 February 2011, the Number Resource Organization announced that the free pool of IPv4 addresses was "fully depleted." Some providers now add a second NAT of their own. Your router then holds an address from 100.64.0.0/10, and the public address belongs to the provider.

Diagram: a laptop with the private address 192.168.1.20 on three paths. On home Wi-Fi the website sees the router's public address. Behind carrier NAT it sees the carrier's shared public address. Through a proxy it sees the proxy's exit address.
Our own diagram, 10 October 2026. Documentation addresses (RFC 5737) stand in for public ones; 100.64.12.9 is from the shared space of RFC 6598.

Which address does a website see?

Always the public address at the end of the path: your router's, your provider's, or a proxy's. The private address never reaches the site, because NAT replaces it and the internet does not route it. It is also why a forged header fools only the servers that believe it, as our page on the fake IP address shows.

A public address tells a site where the connection comes from and which network runs it. A private one tells it nothing. Our IP lookup shows the difference. It answers a public address with a country and a network, and refuses the rest with 400 private_ip.

Our terminal running the test: 14 addresses, Python's is_private and is_global for each, and what our IP lookup answered.
Our own capture, run on 10 October 2026 with Python 3.13.7 and our IP lookup at hproxy.com/api/ip. Only private, documentation and well-known public resolver addresses were used.
AddressWhat it isPython is_private / is_globalOur lookup
192.168.1.20Private, RFC 1918True / False400 private_ip
172.31.255.254Private, end of the middle blockTrue / False400 private_ip
172.32.0.1One block past itFalse / TrueUS, AS21928 T-Mobile USA
100.64.0.1Shared, carrier NATFalse / False400 private_ip
203.0.113.5DocumentationTrue / False400 private_ip
8.8.8.8Public, Google DNSFalse / TrueUS, AS15169 Google
fd12:3456:789a::1IPv6 unique localTrue / False400 private_ip

How to tell public from private in code

In Python, is_global answers "is this public?". Do not read is_private as "RFC 1918". The Python documentation defines it by the IANA registry, so it is also True for loopback, link-local and documentation addresses. And is_private is the opposite of is_global with one exception: for the shared address space, 100.64.0.0/10, "they are both False."

To sort addresses into all four cases, test the blocks yourself:

import ipaddress

RFC1918 = [ipaddress.ip_network(n) for n in ("10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")]
SHARED = ipaddress.ip_network("100.64.0.0/10")
UNIQUE_LOCAL = ipaddress.ip_network("fc00::/7")

def kind(address):
    ip = ipaddress.ip_address(address)
    if ip.is_global:
        return "public"
    if ip.version == 4 and any(ip in net for net in RFC1918):
        return "private (RFC 1918)"
    if ip.version == 4 and ip in SHARED:
        return "shared (carrier NAT)"
    if ip.version == 6 and ip in UNIQUE_LOCAL:
        return "private (unique local)"
    return "not public (reserved)"

for a in ["192.168.1.20", "172.32.0.1", "100.64.0.1", "203.0.113.5", "fd12:3456:789a::1"]:
    print(a, "->", kind(a))

We ran it with Python 3.13.7:

192.168.1.20 -> private (RFC 1918)
172.32.0.1 -> public
100.64.0.1 -> shared (carrier NAT)
203.0.113.5 -> not public (reserved)
fd12:3456:789a::1 -> private (unique local)

A common use is picking the client out of an X-Forwarded-For list, as a 2013 Network Engineering question asked. Skip what is not public, and count only the entries your own proxies added. The rest came from the client, and RFC 7239, the standard for the newer Forwarded header, warns that the client itself can change such values.

Which address do you need?

  • Your router's admin page, a printer, a game on your LAN: the private address.
  • An allowlist on a remote server, or a proxy provider's IP whitelist: the public address. The private one from ipconfig is the wrong answer every time, because no remote server ever sees it. Our guide to IP whitelisting for proxies walks through the setup.
  • Behind carrier NAT: the public address is shared, so an allowlist entry admits your neighbors too. RFC 6269 warns that such lists "will fail when an IP address is no longer sufficient to identify a particular subscriber." Use username and password authentication instead.
  • Where an address is and who runs it: only a public address has an answer.
  • Hiding where you connect from: change the public address. Changing the private one changes nothing a site can see.

What a proxy changes

Only the public side. The site sees the proxy's exit address instead of your router's or your provider's. Your private address stays where it always was, inside your network. Our residential proxies give sites a home connection's address in place of yours. Our free proxy checker shows whether a proxy passes your own address on in a header.

What this page could not check

We did not test from a carrier NAT connection. That path rests on RFC 6598 and RFC 6269, not on our own trace. We tested with Python's library and our own lookup on one day, and did not compare other lookups. Our lookup lists 1.1.1.1 in Australia; we did not check location data against any other source. The registry and Python's rules change over time, and Python changed is_private in version 3.13. We will rerun the test and reread the registry by 10 April 2027.

Sources

  • RFC 1918, Address Allocation for Private Internets, IETF, February 1996: section 3.
  • RFC 4632, Classless Inter-domain Routing (CIDR), IETF, August 2006: section 3.1.
  • RFC 6598, IANA-Reserved IPv4 Prefix for Shared Address Space, IETF, April 2012.
  • IANA IPv4 Special-Purpose Address Registry, last updated 9 October 2025, read 10 October 2026.
  • RFC 4193, Unique Local IPv6 Unicast Addresses, IETF, October 2005.
  • RFC 3022, Traditional IP Network Address Translator (Traditional NAT), IETF, January 2001.
  • Number Resource Organization, "Free Pool of IPv4 Address Space Depleted", 3 February 2011.
  • RFC 6269, Issues with IP Address Sharing, IETF, June 2011: section 13.2.
  • RFC 5737, IPv4 Address Blocks Reserved for Documentation, IETF, January 2010.
  • RFC 6752, Issues with Private IP Addressing in the Internet, IETF, September 2012: section 3.
  • RFC 4291, IP Version 6 Addressing Architecture, IETF, February 2006, and RFC 4862, IPv6 Stateless Address Autoconfiguration, IETF, September 2007.
  • RFC 7239, Forwarded HTTP Extension, IETF, June 2014: section 8.1.
  • Python documentation, ipaddress module, read 10 October 2026.
  • Stack Exchange: Network Engineering question 2283 and Super User questions 777866 and 1107226, read 10 October 2026.
  • HProxy documentation: IP location and ASN API, read 10 October 2026.
  • Our own test on 10 October 2026: ip_test.py with Python 3.13.7 and our IP lookup.

Frequently asked questions

How do I know if an IP address is public or private?
Check the range. 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16 are private, and so is fc00::/7 in IPv6. Some other ranges are not public either, such as 100.64.0.0/10, 169.254.0.0/16 and 127.0.0.0/8. In Python, ipaddress.ip_address(x).is_global is True only for a public address.
Is 100.64.x.x a public IP address?
No. 100.64.0.0/10 is shared address space for carrier-grade NAT. Your provider gives it to your router, and the public address belongs to the provider and is shared with other customers. It is not private in the RFC 1918 sense either, so Python reports it as neither private nor global.
Why does traceroute show a private address right after my router?
Some providers number the links inside their own network with private addresses. RFC 6752 describes the effect: a traceroute across such a network returns the private addresses of its links. A private hop after your router does not by itself mean you lack a public address. Check the address your router holds on its internet side.
Can every device on a network have its own public IP address?
Yes, on a network that hands out public addresses directly, without NAT. A Super User question from a computer camp described exactly that. On IPv6, devices generate global addresses of their own (RFC 4862). On a typical home IPv4 network, all devices share the router's one public address.
Which IP address do I use to whitelist a proxy?
Your public address, the one a what-is-my-IP page shows. The private address from ipconfig never reaches a remote server, so an allowlist entry for it matches nothing. Behind carrier-grade NAT the public address is shared with other customers, so use username and password authentication instead.

Get proxies that are alive right now

Our free proxy list re-checks every exit every few minutes across 100+ countries, with a live last-checked time, so you copy IPs that worked moments ago, not a stale text dump. When the location has to survive a real check, the paid network holds up.

129M+ proxy checks run · 100+ countries · HTTP / HTTPS / SOCKS · re-checked every few minutes · no signup

HProxy.

Honest guides and comparisons on proxies, scraping and staying unblocked, from the team that runs the network.

RSS feed