Why AWS Reserves 5 IP Addresses in Every Subnet (and What Each One Does)
AWS reserves five IP addresses in every VPC subnet: the first four and the last one. A /24 therefore gives you 251 usable addresses rather than 254, and the smallest subnet AWS permits — a /28 — gives you 11 rather than 14. The reservation is not configurable and applies to every subnet in every VPC, including the default one.
The five addresses
Take a subnet of 10.0.7.0/24:
| Address | Reserved for |
|---|---|
10.0.7.0 |
Network address. Standard IPv4, not an AWS invention. |
10.0.7.1 |
The VPC router — the implicit default gateway for the subnet. |
10.0.7.2 |
The Amazon-provided DNS resolver. |
10.0.7.3 |
Reserved by AWS for future use. Currently does nothing. |
10.0.7.255 |
Network broadcast address. |
Three of those deserve a closer look.
.1 — the VPC router
Every subnet’s default gateway is the base address plus one. This is not a device you can see, log into, or place in a security group; the VPC router is implemented in the network fabric itself, distributed across the availability zone rather than running anywhere in particular.
That distributed implementation is why VPC routing behaves in ways that surprise people arriving from physical networking. There is no router to overload, no interface to saturate, and no failover event when a router dies — but also no traceroute hop to see, and no way to run a packet capture on the gateway. Route tables are the only interface to it.
.2 — the DNS resolver
The Amazon-provided DNS server sits at the VPC CIDR base plus two, not the subnet base plus two. For a VPC of 10.0.0.0/16 the resolver is 10.0.0.2 regardless of which subnet you are in — but AWS still reserves the .2 in every subnet, which is why you will find it in the reservation list of a subnet that is nowhere near the VPC base.
The same resolver is reachable at the link-local address 169.254.169.253, which is stable no matter what the VPC CIDR is. That is the address to hard-code in a golden AMI that might be launched into VPCs with different ranges.
Two limits on this resolver matter in production. It enforces 1,024 packets per second per elastic network interface, and that limit is not adjustable. It also only answers queries originating inside the VPC — an on-premises resolver cannot query it without a Route 53 Resolver inbound endpoint.
.3 — reserved for future use
AWS has held this address since the beginning of VPC and has never said what for. It is not used by anything today. You cannot assign it, and there is no flag to reclaim it.
The last address — broadcast
AWS reserves the broadcast address even though VPCs do not support broadcast or multicast on the standard data plane. Broadcast traffic is silently dropped, which is worth knowing before you try to lift-and-shift anything that depends on it: older clustering software, some licence servers, PXE boot, and certain discovery protocols all fail quietly in a VPC for this reason. Transit Gateway multicast exists as a separate feature for the multicast half of that problem; there is no broadcast equivalent.
What this does to subnet sizing
The reservation is a flat five addresses regardless of subnet size, which means it hurts small subnets disproportionately:
| Prefix | Total | Usable in AWS | Lost to reservation |
|---|---|---|---|
| /28 | 16 | 11 | 31% |
| /27 | 32 | 27 | 16% |
| /26 | 64 | 59 | 8% |
| /24 | 256 | 251 | 2% |
| /20 | 4,096 | 4,091 | 0.1% |
| /16 | 65,536 | 65,531 | <0.1% |
At /28 — the AWS minimum — nearly a third of the subnet is gone before you launch anything. That is usually fine, because /28s are for endpoint ENIs and appliance interfaces rather than fleets, but it is the reason “I need 12 addresses so a /28 will do” turns into a failed launch.
The addresses you also lose to infrastructure
The five reserved addresses are only the floor. In a real subnet, several things consume addresses that people do not count:
- NAT gateway — one address per gateway, per subnet.
- Interface VPC endpoints — one ENI, and therefore one address, per endpoint per subnet.
- Load balancer nodes — an Application Load Balancer places at least one ENI in each subnet you enable and adds more as it scales. AWS requires at least eight free addresses per subnet for this reason.
- Transit Gateway attachments — one ENI per subnet per attachment.
- RDS, ElastiCache, Redshift — each managed instance takes an address, and Multi-AZ takes one in the standby subnet too.
- Kubernetes pods under the AWS VPC CNI — this is the big one. Each pod gets a real VPC address. A node running 50 pods consumes 50 subnet addresses, not one.
The VPC CNI case deserves a number. A three-AZ EKS cluster on m5.large nodes with 29 pods each, running 30 nodes, consumes roughly 900 addresses for pods alone — comfortably more than three /24 subnets provide. Sizing worker subnets at /19 or /20 is normal, and prefix delegation mode changes the arithmetic again by allocating /28 blocks per ENI rather than individual addresses.
You cannot resize a subnet
This is the part that turns an arithmetic error into a migration project. A subnet’s CIDR is fixed at creation. There is no modify operation, no expand, no merge. If you undersize a subnet, the options are:
- Create a new, larger subnet and move the workloads into it.
- Add a secondary CIDR block to the VPC and build new subnets from it.
- Live with it and scale sideways into additional subnets.
None of these is quick when the subnet holds a database with a fixed endpoint or a load balancer with a stable DNS name. Size upward at creation — addresses in a private range cost nothing, and the /16 ceiling on a VPC is generous enough that being generous with subnets rarely runs you out.
Checking free addresses
The current free count is exposed directly:
aws ec2 describe-subnets \
--query 'Subnets[].{Id:SubnetId,Cidr:CidrBlock,Az:AvailabilityZone,Free:AvailableIpAddressCount}' \
--output table
AvailableIpAddressCount already accounts for the five reserved addresses and everything currently allocated, so it is the number to alert on. A CloudWatch alarm on a subnet dropping below, say, 10% free addresses catches CNI exhaustion before it becomes pods stuck in ContainerCreating.
Other clouds
The reservation is not unique to AWS, and the counts differ:
- Azure reserves five per subnet — the network address, three for the platform (default gateway, DNS mapping, and one for future use), and the broadcast address. Same arithmetic as AWS.
- Google Cloud reserves four in the older behaviour: network address, default gateway, second-to-last, and broadcast. Newer subnet modes changed this, so check the current documentation for the mode you are using.
If you are building a multi-cloud address plan, the safest assumption is five and the safest habit is to check AvailableIpAddressCount or its equivalent rather than doing the arithmetic yourself.
Related
- VPC subnet calculator — enter any CIDR and see both the traditional and AWS usable counts
failed to assign an IP address to container— what subnet exhaustion looks like on EKS- 100.64.0.0/10 for EKS address exhaustion — what to do when the VPC has no room left