/31 subnet: 255.255.255.254, 2 addresses

2 addresses (2 usable hosts)

A /31 has the netmask 255.255.255.254 and holds 2 addresses, and both are usable hosts. By the usual rule a /31 would have nothing left after its network and broadcast addresses, but RFC 3021 defines /31s for point-to-point links, which need neither: 10.0.0.0/31 puts one end on 10.0.0.0 and the other on 10.0.0.1.

The numbers

First host     10.0.0.0
Last host      10.0.0.1
Netmask        255.255.255.254
Wildcard       0.0.0.1
Addresses      2
Usable hosts   2

The tool, and its API, leave out the broadcast address for a /31 and add RFC 3021’s note.

How it fits

A /30 holds two /31s and a /24 holds 128. A /31 splits into 2 /32s.

Where you’ll see it

A link between two routers has exactly two ends, so a /31 numbers it with no waste. Data center fabrics, where every leaf switch links to every spine, use /31s for those links and the BGP sessions on them: a /24 numbers 128 links as /31s, against 64 as /30s. Most numbering that was done with /30s can move to /31s once both ends support them.

Gotchas

  • Point-to-point only. RFC 3021 is for a link with exactly two ends. A LAN segment with a third device, such as a monitoring host or a second router, needs a /29 or larger.
  • Both ends must be /31. If one side is configured 10.0.0.1/30, it treats 10.0.0.0 as a network address rather than its neighbor, and the link misbehaves.
  • Not every platform. AWS subnets stop at /28 and Azure and Google Cloud at /29, so cloud subnets can’t be /31s. Older software that computes usable hosts as 2^(32 − n) − 2 gets 0 and rejects them. Python’s ipaddress follows RFC 3021: hosts() returns both addresses.
  • IPv6 does it differently. The counterpart on an IPv6 link is a /127, which RFC 6164 recommends for links between routers; the tool counts both of its addresses as usable, with a note saying why.

In your stack

! Cisco IOS
interface Ethernet1/1
 ip address 10.0.0.0 255.255.255.254

# Junos
set interfaces xe-0/0/0 unit 0 family inet address 10.0.0.0/31
ip addr add 10.0.0.1/31 dev eth1        # Linux, the other end
import ipaddress
list(ipaddress.ip_network("10.0.0.0/31").hosts())
# [IPv4Address('10.0.0.0'), IPv4Address('10.0.0.1')]
# Terraform: the second /31 of a /30, and the netmask
cidrsubnet("10.0.0.0/30", 1, 1)         # "10.0.0.2/31"
cidrnetmask("10.0.0.0/31")              # "255.255.255.254"

Try it in the CIDR & Subnet Calculator

10.0.0.0/31 Private (RFC 1918)

RFC 3021: a /31 has no network or broadcast address, so both addresses are usable.

Network10.0.0.0/31
Netmask255.255.255.254
Wildcard0.0.0.1
Mask, binary11111111.11111111.11111111.11111110
First host10.0.0.0
Last host10.0.0.1
Addresses2
Usable hosts2
KindPrivate (RFC 1918)

Enter a longer prefix to list the subnets, like /32.

Runs in your browser. Nothing you enter is sent anywhere.