Private IP Address Ranges (RFC 1918) by Block
Private IP address ranges follow RFC 1918, not every nonpublic IP. Get exact CIDR blocks, address counts, and Python checks for routing and proxy policies.
The private IP address ranges defined by RFC 1918 are 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. Together, they contain 17,891,328 IPv4 addresses, with individual blocks ranging from 65,536 to 16,777,216 addresses. This reference gives you the exact boundaries, subnet masks, and runnable checks for routing, scraping infrastructure, and proxy configuration.
TL;DR
- RFC 1918 defines three private IP address ranges: 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16.
- Only 172.16.0.0 through 172.31.255.255 is private within the 172 address space.
- Your worker's private address is not what a target sees through a proxy; the target sees the proxy's exit.
- Use explicit CIDR membership checks when your application needs RFC 1918 classification.
To check a specific block, the subnet calculator shows its range and mask, and IPv4 CIDR block sizes covers the prefix arithmetic for every size.
RFC 1918 blocks and address counts
An address count measures every IPv4 address contained in a block. It is not a count of assignable hosts on one subnet.
| Private block | First address | Last address | Subnet mask | Total addresses |
|---|---|---|---|---|
10.0.0.0/8 | 10.0.0.0 | 10.255.255.255 | 255.0.0.0 | 16,777,216 |
172.16.0.0/12 | 172.16.0.0 | 172.31.255.255 | 255.240.0.0 | 1,048,576 |
192.168.0.0/16 | 192.168.0.0 | 192.168.255.255 | 255.255.0.0 | 65,536 |
| Overall: all three blocks | Separate ranges | Separate ranges | No single mask | 17,891,328 |
The 10.0.0.0/8 block is the largest, with 16,777,216 addresses; 192.168.0.0/16 is the smallest, with 65,536. The overall row is a sum of three separate blocks, not a continuous range you can represent with one equivalent CIDR.
Source: IETF RFC 1918, Address Allocation for Private Internets, February 1996, Section 3, covering IPv4 private address space. Counts follow from each prefix length; this table does not measure available hosts, deployed devices, or network performance.
Why this matters
A private address identifies an interface within a network that uses that address space. It does not identify a globally unique device. Two unrelated companies can both use 10.0.0.10 without coordinating, provided their networks do not need to route directly between those overlapping addresses.
That distinction matters when you join networks. A VPN, cloud connection, or company acquisition can bring identical subnets into the same routing environment. Your route table then needs an explicit solution to the overlap, not just another private address.
For your infrastructure inventory, record both the address and its network context. An isolated IP string is insufficient when different environments reuse the same block.
How to use these address counts
Choose address space around your topology, not the largest number in the table. More addresses do not make a network faster or more secure. The block size gives you room to subdivide; routing and access controls determine how those subdivisions behave.
- Best for large internal address plans:
10.0.0.0/8. Its 16,777,216 addresses give you the most subdivision room. The trade-off is overlap: selecting this block does not establish that a partner, VPN client, or acquired network uses something different. Reserve distinct allocations for environments before assigning individual hosts. - Best for a mid-sized plan:
172.16.0.0/12. Its 1,048,576 addresses, spanning second-octet values 16 through 31, leave room to subdivide without taking the largest block. Check it against the networks you will connect to, as with any range. The limitation is an easy configuration mistake: matching all addresses beginning with172captures addresses outside RFC 1918. - Best for compact internal allocations:
192.168.0.0/16. Its 65,536 addresses support smaller subdivisions without using the larger blocks. The constraint is capacity relative to the other two ranges. Check existing remote-access networks before choosing an allocation.
These are planning labels, not guarantees that a block will suit your deployment. Review existing routes, expected subdivisions, and connected networks first. Keep a written allocation map so development, staging, production, and remote access do not independently choose overlapping space.
Read the prefix, not just the first octet
CIDR notation combines a starting network address with a prefix length. IPv4 addresses contain 32 bits. A /8 prefix fixes 8 bits and leaves 24 address bits, producing 16,777,216 addresses.
The same arithmetic gives /12 its 1,048,576 addresses and /16 its 65,536 addresses. Prefix lengths describe boundaries, not labels such as home, office, or cloud. Any organization can subdivide any RFC 1918 block according to its routing plan.
Do not classify 172.0.0.0/8 as private. The RFC 1918 portion starts at 172.16.0.0 and ends at 172.31.255.255. For example, 172.15.255.255 and 172.32.0.0 are outside that portion.
The same boundary discipline applies to 192.168.0.0/16. An address beginning with 192 is not automatically private. Use the complete prefix rather than a visual guess or a string rule that tests only the first component.
Total addresses are not usable-host counts
A block's total includes every address in its mathematical range. Host assignment depends on how you split that block and how your network implements those subnets. You cannot turn the overall total into an available-device count without an allocation plan.
For example, a conventional IPv4 /24 subnet contains 256 addresses. Reserving its network and broadcast addresses leaves 254 conventional host addresses. That calculation describes the subnet, not every possible deployment: point-to-point /31 links have different address semantics under RFC 3021.
Cloud platforms can also reserve addresses within your allocated subnet. Read the platform's current rules before sizing capacity. Do not assume the conventional host calculation is the number your platform lets you assign.
For a capacity worksheet, separate three fields: allocated block size, subnet structure, and assignable addresses under your platform's rules. Keeping them separate prevents a mathematically correct block count from becoming an incorrect capacity forecast.
Nonpublic does not mean RFC 1918
RFC 1918 is one specific classification. Other addresses have special purposes without belonging to its three blocks. This distinction matters when you write filters, diagnose connectivity, or interpret an address returned by a library.
| Address space | Purpose | RFC 1918 private? | Best use of the classification |
|---|---|---|---|
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 | Private IPv4 addressing | Yes | Internal IPv4 allocation checks |
127.0.0.0/8 | IPv4 loopback | No | Identifying local-host destinations |
169.254.0.0/16 | IPv4 link-local addressing | No | Diagnosing local-link addressing |
100.64.0.0/10 | Shared address space, including carrier-grade NAT use | No | Separating shared addressing from RFC 1918 |
Sources: RFC 1122, October 1989, for IPv4 loopback; RFC 3927, May 2005, for IPv4 link-local addressing; and RFC 6598, April 2012, for shared address space. These standards cover different purposes, not interchangeable private-network options.
The advantage of separate classifications is precision. The limitation is that no single label answers every policy question. An address outside RFC 1918 is not automatically a safe or publicly reachable destination.
Check RFC 1918 membership with Python
Use explicit network membership when your requirement is exactly RFC 1918. Python's ipaddress module provides parsing and CIDR checks without a third-party dependency. Parse the address before applying policy so malformed input does not pass through a string comparison.
Run this script with Python 3:
from ipaddress import ip_address, ip_network
RFC1918 = tuple(ip_network(cidr) for cidr in (
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
))
def is_rfc1918(value: str) -> bool:
address = ip_address(value)
if address.version != 4:
return False
return any(address in network for network in RFC1918)
samples = (
"10.0.0.1",
"172.15.255.255",
"172.16.0.0",
"172.31.255.255",
"172.32.0.0",
"192.168.1.1",
"127.0.0.1",
"100.64.0.1",
"::1",
)
for sample in samples:
print(f"{sample}: {is_rfc1918(sample)}")The check returns True only for IPv4 addresses inside the three listed blocks. Loopback, shared address space, and any non-IPv4 input return False. Invalid address syntax raises ValueError; handle that exception as invalid input in your application rather than treating it as an acceptable destination.
Do not substitute address.is_private for an exact RFC 1918 test. Python uses that property for a broader classification of addresses that are not globally reachable, with documented exceptions. Explicit membership keeps your RFC 1918 requirement visible and independent of that broader label.
Add boundary cases to your tests. Checking only 192.168.1.1 proves little about your handling of the 172.16.0.0/12 block. Test the first and last addresses, plus addresses immediately outside the boundaries.
Separate the client address from the proxy exit
Your laptop or worker can use an RFC 1918 address while an external website sees a different source address. NAT translates addresses for traffic crossing a network boundary. A forward proxy instead makes an upstream connection on your application's behalf.
These are different mechanisms. A private client address does not reveal the public source address observed by a target. Conversely, a target's observed address does not tell you which private address your worker uses internally.
Keep three roles separate when troubleshooting:
- Client address: the source interface used by your application inside its network.
- Proxy endpoint: the destination your application connects to for proxy service.
- Observed exit: the source address the target sees on the upstream connection.
The proxy endpoint and observed exit need not be identical. Record them separately in connection diagnostics. If your request fails, establish whether the failure occurred before reaching the proxy or during the proxy's connection to the target.
If you need fixed outbound identities rather than a diagnosis, see dedicated datacenter proxies and their connection setup; pricing has the plans.
For scraping workflows, changing the proxy exit does not fix an overlapping internal route. Likewise, changing a worker's private address does not prove that the target sees a different exit. Check the layer responsible for the symptom before changing configuration.
Do not use this table as an SSRF defense
Blocking RFC 1918 destinations is not a complete server-side request forgery defense. Loopback, link-local destinations, and other special-purpose addresses require their own policy, and so does any address family outside IPv4. A hostname also needs resolution checks rather than a check of its text alone.
Redirects introduce another destination decision. Validate the destination after each redirect, or disable redirects when the application does not need them. Ensure the checked address is the address used for the connection so DNS changes do not defeat validation.
Prefer a list of permitted destinations when your application only needs known services. For broader fetching, apply destination restrictions alongside network-level egress controls. The Python example above classifies RFC 1918 membership; it is not a complete URL validator or security boundary.
A proxy changes which system makes the upstream connection. If the proxy resolves the hostname remotely, local DNS validation alone does not establish the address the proxy will reach. Apply the policy where resolution and connection occur.
FAQ
What are the private IP address ranges?
The RFC 1918 private IPv4 ranges are 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. They contain 17,891,328 addresses in total and are separate blocks, not one continuous range.
Is every address starting with 172 private?
No. Only 172.16.0.0 through 172.31.255.255 belongs to the RFC 1918 private block. Test membership in 172.16.0.0/12 rather than matching the first octet.
Is 192.168.1.1 a private IP address?
Yes. 192.168.1.1 belongs to 192.168.0.0/16. Its role as a router, host, or other interface depends on your network configuration.
Is 100.64.0.1 an RFC 1918 private address?
No. 100.64.0.1 belongs to the shared address space 100.64.0.0/10 defined by RFC 6598. It is separate from the three RFC 1918 blocks.
Does a private IP address make my device secure?
No. Private addressing is not an access-control policy. You still need appropriate firewall rules, authentication, and network segmentation.
Can two networks use the same private IP addresses?
Yes. Independent networks can reuse RFC 1918 addresses. Connecting overlapping networks requires a routing, translation, or renumbering solution.
Will a website see my private IP when I use a proxy?
The target sees the source address of the proxy's upstream connection, not your worker's RFC 1918 source address. Application data or headers can disclose other information separately, so this does not guarantee anonymity.
One last thing
Test the boundary that looks private but is not: 172.32.0.0. It sits immediately outside the RFC 1918 block. A classifier that accepts it because it starts with 172 is wrong, even if every familiar address in your test suite passes.
Add that case before changing your routing or proxy rules. A small boundary test catches a large classification error.
Related guides
- IPv4 CIDR block sizes and address counts
- aiohttp SOCKS5 proxy: authentication and bounded concurrency
- curl SOCKS5 vs HTTP proxy: auth and response checks, for the connection setup rather than address classification
- Python Requests proxy sessions: timeouts, retries and resume
- Proxy rotation for web scraping