Two IPv4 prefixes overlap when some address belongs to both, and under Classless Inter-domain Routing () that means one lies wholly inside the other, as (RFC) 4271 notes for routes (RFC 4271, section 9.1.4). On purpose, that is a specific route inside a broader one; by accident, one subnet on two interfaces or two sites on one block. Gaps are the mirror image: addresses in a parent block that no prefix covers. By the end you can prove the nesting rule in binary, tell design from fault, account for every address, explain why virtual private network () tunnels and cloud peering refuse overlaps, and check it all with ip route, Python and the CIDR / Subnet Calculator.

Two prefixes either nest or never meet

CIDR replaced address classes with hierarchical prefixes (RFC 4632, section 3): an address, a slash and the number of significant bits, 0 to 32, naming a power-of-two block (section 3.1); CIDR notation explained reads the slash. RFC 1812 defines a network prefix as "a contiguous set of bits at the more significant end of the address" (RFC 1812, section 2.2.5.2). Membership is a masked comparison, written as pseudo-code in 1985 (RFC 950, section 2.2):

IF bitwise_and(dg.ip_dest, my_ip_mask)
                          = bitwise_and(my_ip_addr, my_ip_mask)

Routers apply it as Basic Match, keeping only routes whose most significant route.length bits equal the destination's (RFC 1812, section 5.2.4.3). Take P/m and Q/n, m no greater than n, and compare their first m bits: equal, and every address of Q/n starts with them, so Q/n lies inside P/m; different, and no address starts with both, so they are disjoint. There is no third outcome. RFC 4271 makes the point for 's Network Layer Reachability Information (NLRI): "Because BGP encodes NLRI using IP prefixes, overlap will always exhibit subset relationships" (RFC 4271, section 9.1.4). In binary, prefix bits before the bar:

198.51.100.0/24    110001100011001101100100|00000000
198.51.100.128/25  1100011000110011011001001|0000000
198.51.100.0/25    1100011000110011011001000|0000000

The /24 and the upper /25 share their first 24 bits, so the /25 is inside the /24; the two /25s differ in bit 25 and share nothing.

A partial overlap, neither range containing the other, therefore needs a range that is not a prefix: 10.0.0.64 to 10.0.0.191 shares 64 addresses with 10.0.0.0/25, yet as prefixes it is 10.0.0.64/26, inside the /25, and 10.0.0.128/26, outside it. The other source is a discontiguous mask, which can leave two equally specific routes matching one destination; RFC 1812 calls this "the reason the use of discontiguous subnet masks is not permitted" (RFC 1812, section 10.2.2).

Longest match: the overlap you build on purpose

Nesting is what longest match, detailed in static routes, longest prefix match and administrative distance, feeds on. Of the routes that survive Basic Match, RFC 1812 keeps those with the longest prefix and discards the rest; if none survives, the packet is discarded as unreachable (RFC 1812, section 5.2.4.3):

DestinationRoutes that matchRoute used
198.51.100.1300.0.0.0/0, 198.51.100.0/24, 198.51.100.128/25198.51.100.128/25
198.51.100.100.0.0.0/0, 198.51.100.0/24198.51.100.0/24
203.0.113.50.0.0.0/00.0.0.0/0

The internet relies on the rule: a re-homed organisation's new provider announces a specific route for it, and "this advertisement is preferred over provider aggregates because it is a longer match" (RFC 4632, section 4.1). If a more-specific is withdrawn, its destinations stay reachable through the covering route (RFC 4271, section 9.1.4).

Gaps, and accounting for every address

A gap is the part of a parent block that no assigned prefix covers; RFC 4632 calls such space holes (RFC 4632, section 6.1). Subtract the assignments from the parent, write each free run as the largest aligned blocks that fit, and check that assigned plus free equals the parent, as in an allocation worked end to end. In 198.51.100.0/24:

BlockStatusAddresses
198.51.100.0/26assigned64
198.51.100.64/27free32
198.51.100.96/27assigned32
198.51.100.128/26free64
198.51.100.192/29free8
198.51.100.200/29assigned8
198.51.100.208/28free16
198.51.100.224/27free32

Assigned 104 plus free 152 makes the /24's 256. The run from 198.51.100.208 to 198.51.100.255 holds 48 addresses, not a power of two, so it becomes a /28 and a /27.

Holes also come and go. RFC 4632's provider, holding 10.24.0.0/13, connects six sites in order (RFC 4632, section 6.1). After 10.24.0.0/21 and 10.24.16.0/20, the hole 10.24.8.0/21 stays open until 10.24.8.0/22 and 10.24.12.0/22 fill it, and the four then aggregate exactly to 10.24.0.0/19. The diagram prints the last as a /20; verified erratum 2955 corrects it to the /22 of the text, the value used above (RFC 4632 errata). After six sites, 9,216 of 524,288 addresses are assigned and eight gaps hold the rest, yet the provider advertises the whole /13 (RFC 4632, section 6.2).

That is safe only with a discard route: "A router that generates an aggregate route for multiple, more-specific routes must discard packets that match the aggregate route, but not any of the more-specific routes" (RFC 4632, section 5.1), or packets for covered but unreachable addresses can loop. In practice that is a discard or null route per advertised aggregate (section 5.2), with the overlapping more-specifics kept internal (section 5.4); route summarisation shows the failure without one, and supernetting the gap-free set that collapses to one block.

When an overlap is a fault

An overlap is a fault when two parts of a network claim the same addresses. Put one subnet on two interfaces and RFC 1812's connected-network test, comparing the destination with each interface's prefix, matches both and leaves no single answer: "If they are equal to each other, the packet can be transmitted through the corresponding network interface" (RFC 1812, section 5.2.4.2).

A router may refuse the duplicate outright. In a Cisco Community thread of December 2016, a forum report rather than Cisco documentation, a poster configuring a second interface with ip address 10.10.10.250 255.255.255.248 reported "% 10.10.10.248 overlaps with GigabitEthernet8" (Cisco Community thread, December 2016); with that mask, 10.10.10.250 lies in 10.10.10.248/29, the network the message names.

Between sites, private space invites collisions: "Addresses within this private address space will only be unique within the enterprise" (RFC 1918, section 3). Merging two private networks may force renumbering where addresses are no longer unique (section 4), and RFC 1918's defence is to pick sub-blocks at random from the private pool (section 5); Private IPv4 address space and RFC 1918 covers the ranges.

Longest match is also how a route is hijacked: "Traffic can be hijacked by advertising a prefix for a given destination that is more specific than the aggregate that is normally advertised for that destination" (RFC 4632, section 12). On 24 February 2008 Pakistan Telecom, Autonomous System (AS) 17557, announced 208.65.153.0/24 without authorisation, inside YouTube's 208.65.152.0/22, and the /24 won wherever it spread; YouTube answered with the same /24 and then two /25s (RIPE NCC, YouTube Hijacking case study), a story BGP: the trust fall the whole internet is standing on tells in full. RFC 4632's defences are trust between providers, strong border filters and caps on accepted prefix lengths derived from Regional Internet Registry (RIR) guidelines (RFC 4632, section 12).

Where overlaps bite: VPNs and cloud peering

Across a VPN, overlap keeps traffic at home: a packet for an address inside the local range, as RFC 2663 says of colliding realms, "would be forwarded to the internal node rather than through the device to the external realm" (RFC 2663, section 4.3). Microsoft's VPN gateway documentation says the address spaces "must not overlap otherwise the communication would fail" (Microsoft Learn, About NAT on Azure VPN Gateway).

Cloud peering refuses overlaps outright. Google Cloud fails a Virtual Private Cloud () peering if overlapping subnets exist, and one sentence covers every case: "No subnet IP range can exactly match, contain, or fit within another subnet IP range in a peered VPC network" (Google Cloud, VPC Network Peering). Identical, containing, contained: no word for partial, because prefixes have none. Amazon Web Services () agrees: "You cannot create a connection between VPCs that have matching or overlapping IPv4 or IPv6 CIDR blocks" (Amazon VPC Peering Guide), even if only the non-overlapping blocks would be used (same page). Azure requires non-overlapping address spaces for peered virtual networks (Microsoft Learn, Create, change, or delete Azure virtual network peering).

Translating around an overlap, or keeping networks apart

Ordinary NAT assumes that the private addresses do not overlap the external ones (RFC 2663, section 4.1). When they do, both addresses must change: "Twice NAT is necessary when private and external realms have address collisions" (section 4.3), with a translator at one end of the tunnel or both (section 6.1); NAT explained covers the basics. Three vendors document worked cases:

ProductOverlapping networksUnique ranges used instead
FortiOS site-to-site VPNheadquarters and branch, both 192.168.111.0/2410.1.1.0/24 (headquarters), 10.2.2.0/24 (branch)
Azure VPN Gateway NATa virtual network and two branches, all 10.0.1.0/24192.168.1.0/24, 192.168.2.0/24, 192.168.3.0/24
AWS private NAT gatewaytwo VPCs, both 10.0.0.0/16100.64.1.0/24 and 100.64.2.0/24

Fortinet translates both addresses, and "The virtual subnets must be the same size as the overlapping subnet" (Fortinet, Site-to-site VPN with overlapping subnets); Azure's external mappings may overlap neither each other nor networks connected without NAT (Microsoft Learn, About NAT on Azure VPN Gateway); AWS has the IP team decide first which ranges may overlap and which must stay routable (Amazon VPC User Guide, NAT gateway use cases); Google's Private NAT reaches only non-overlapping destination subnets, none across VPC Network Peering (Google Cloud, Private NAT). The overlapping side is hidden; every destination still needs a unique address.

Providers separate rather than translate. RFC 4364 lets VPNs with no sites in common overlap, typically in RFC 1918 space, as long as each address is unambiguous within its VPN (RFC 4364, section 1.3). The provider's edge routers (PE routers) turn a prefix shared by several VPNs into unique VPN-IPv4 prefixes, and the Route Distinguisher (RD) exists only for that: "The purpose of the RD is solely to allow one to create distinct routes to a common IPv4 address prefix" (section 4.1).

Seeing overlaps and gaps

An overlap is a state of routing tables and plans, not a field in a packet, so a capture will not show it. On Linux, with the three routes of the longest-match table installed:

ip route show root 198.51.100.0/24
ip route show match 198.51.100.130/32
ip route show exact 198.51.100.0/24
ip route get 198.51.100.130
ip route get fibmatch 198.51.100.130

In ip-route(8), root selects routes with prefixes not shorter than the one given (the /24 and the /25), match those not longer, the covering routes (all three), and exact that prefix alone (ip-route(8), Linux manual page). ip route get prints the route the kernel would use, and fibmatch the full matched route, the /25. The aggregating router's discard route is a blackhole, whose packets are discarded silently (ip-route(8)):

ip route add blackhole 198.51.100.0/24

Python's ipaddress module runs in the Python playground, real CPython 3.14 in the browser. Its overlaps(), subnet_of(), address_exclude() (for contained networks only), collapse_addresses() and summarize_address_range() cover the audit (Python 3.14 documentation, ipaddress). The gaps, the balance and the strict default:

>>> from ipaddress import ip_network, collapse_addresses
>>> ip_network("198.51.100.0/25").overlaps(ip_network("198.51.100.128/25"))
False
>>> ip_network("198.51.100.128/25").subnet_of(ip_network("198.51.100.0/24"))
True
>>> parent = ip_network("198.51.100.0/24")
>>> used = [ip_network(p) for p in
...         ("198.51.100.0/26", "198.51.100.96/27", "198.51.100.200/29")]
>>> free = [parent]
>>> for u in used:
...     free = [g for f in free
...             for g in (f.address_exclude(u) if u.subnet_of(f) else [f])]
...
>>> for g in sorted(free):
...     print(g)
...
198.51.100.64/27
198.51.100.128/26
198.51.100.192/29
198.51.100.208/28
198.51.100.224/27
>>> list(collapse_addresses(free + used))
[IPv4Network('198.51.100.0/24')]
>>> ip_network("10.0.0.64/25")
Traceback (most recent call last):
  ...
ValueError: 10.0.0.64/25 has host bits set
>>> ip_network("10.0.0.64/25", strict=False)
IPv4Network('10.0.0.0/25')

The CIDR / Subnet Calculator audits a plan in its Overlap / gap mode: up to 1,024 prefixes, separated by newlines, commas or spaces, with the parent in Scope (optional, enables gap detection). It labels each overlapping pair identical to, contains, is inside or partially overlaps, with the shared range and its size, and, only when a scope is set, lists the free blocks under Gaps in scope, each the largest aligned block that fits. Supernet mode shows whether a gap-free set collapses: RFC 4632's first four sites give 10.24.0.0/19.

Unlike Python, the calculator masks host bits silently. 10.0.0.64/25 beside 10.0.0.0/25 is reported as identical; the diagram's uncorrected 10.24.12.0/20 beside 10.24.0.0/21 is read as 10.24.0.0/20, so 10.24.0.0/21 appears inside 10.24.12.0/20, overlapping from 10.24.0.0 to 10.24.7.255, 2,048 addresses. A mistyped prefix can thus pose as an overlap: the sign is an overlap starting below the address you typed. The same masking is why the partial label never appears.

What to remember

  • Two IPv4 prefixes either nest or share nothing: compare their first m bits, m being the shorter length.
  • A partial overlap needs a non-prefix range or a discontiguous mask, which RFC 1812 does not permit.
  • A more-specific route announced on purpose wins by longest match; one subnet on two interfaces, or two sites on one block, is a fault.
  • Gaps are the parent minus the assignments, as the largest aligned blocks; assigned plus free must equal the parent.
  • An aggregate may cover gaps only with a discard route for itself, such as a Linux blackhole route.
  • AWS, Azure and Google Cloud refuse to peer overlapping ranges; across a VPN, a packet for an overlapping address stays local.
  • Translating one or both sides, or separating routing tables with route distinguishers, works around an overlap; private blocks chosen at random are less likely to collide.

Sources