The reachability chain
1
Attach an internet gateway to the VPC
2
Add the default route to the subnet's route table
3
Attach the floating IP to the interface
400: “the interface’s subnet has no default route (0.0.0.0/0) to an
internet gateway — attach an internet gateway to the VPC and add a default
route first”.4
Allow the traffic in a security group
An interface in no security group drops everything.
Security groups covers the default posture.
The guard runs in both directions. Deleting the
0.0.0.0/0 route while
floating IPs still depend on it is refused too: “cannot delete the default
route: N floating IP(s) in this route table’s subnets depend on it for
internet reachability — detach them first”. Any other route deletes normally,
and so does the default route once nothing is attached.Route tables
Every VPC gets a table calledmain when it is created. Subnets land there
unless they name a route_table_id. Table names are unique per VPC, and main
is reserved — you cannot create a second table with that name.
Routes
destination is a CIDR, and exactly one target field must be set:
string
A unicast next hop inside this VPC’s CIDR, same family as the
destination. Loopback, link-local, multicast and unspecified addresses are
rejected, and so is anything outside the VPC. This is for appliances and NICs
you run yourself — internet egress is not expressible this way, because a
gateway target is what pins the route to your own VPC’s uplink.
uuid
The gateway must be attached, and attached to this VPC. Otherwise the
create fails with “target internet gateway is not attached to a VPC” or
“target internet gateway is attached to a different VPC”.
uuid
IPv4 destinations only. A v6 destination is refused with “nat gateway targets
do not support IPv6 destinations” — v6 needs no address translation.
uuid
IPv6 destinations only, and refused the other way round.
One route per destination
A table holds at most one route to a given destination. A second one is refused with409.
A route’s destination and target are immutable; PATCH only takes
description and tags. To repoint a route, delete it and create the
replacement.
Internet gateways
A gateway is created detached and attached to a VPC in a separate call. Both sides are one-to-one:- A VPC can have at most one gateway attached (“target VPC already has an attached gateway”).
- A gateway can be attached to at most one VPC (“already attached — detach first”).
0.0.0.0/0 to each route table that should be
public, which is what lets one VPC hold public and private subnets side by side.
Detach refuses while any route still targets the gateway, and delete refuses
while it is either attached or referenced by a route. Rewrite the routes first.
NAT gateways
A NAT gateway gives private IPv4 subnets outbound access without making them reachable from outside.string, stable
Allocated from the regional public pool and fixed for the gateway’s lifetime.
This is the address your outbound traffic appears from, so it is the one you
give a third party to allowlist.
name, subnet_id and
external_ip are immutable; the subnet it lives in cannot be deleted while it
is there; and the gateway cannot be deleted while a route references it.
Egress-only gateways: the IPv6 case
IPv6 has no address translation, so an instance in a dual-stack subnet reaches the internet as its own global address. “Outbound only” cannot be built from a NAT gateway the way it can for IPv4 — an egress-only gateway is how you express it.::/0 at it. Subnets on that table then get outbound IPv6
and the replies to their own connections, while connections the internet
initiates are dropped.
The internet gateway requirement bites at that route, not at the create: an
egress-only gateway uses the VPC’s internet gateway for its uplink, so the
::/0 route is refused with “egress-only gateway requires an internet gateway
attached to its VPC” if there is none.
Delete refuses while a route still references it.
IPv6 reachability is the route, not the address
Adding, changing or removing that route flips the posture of every instance
already running on that route table, not only ones created afterwards.
Floating IPs
A floating IP is a public IPv4 address from the region’s pool. The create takes onlydescription and tags — the address is assigned to you:
Attach
Attach
POST /v1/floating-ips/{floating_ip_id}/attach with interface_id.
Re-attaching to a NIC that already holds it is a no-op success.It is refused when:- the interface’s subnet has no
0.0.0.0/0route to an internet gateway (400); - the interface already carries a different floating IP (
409, “interface is already attached to floating IP address”) — a NIC has one public identity; - the address already has a member, so a second one would make it an
anycast address (
409, see below); - the address is bound to a resource that owns its own bindings, such as a load balancer or an instance pool — attach and detach it there.
Detach
Detach
POST /v1/floating-ips/{floating_ip_id}/detach. The body is optional: an
ordinary floating IP has at most one member, so naming interface_id or
omitting it detaches the same address.It is idempotent. Detaching an already-detached address, or naming a NIC
that is not a member, returns 200 with the row unchanged.Release
Release
DELETE /v1/floating-ips/{floating_ip_id} returns the address to the pool.
Refused with 409 while it is still attached, or while it belongs to an
instance pool. Detach first.Reading the bindings
members is authoritative. attached_to_interface_id is a legacy
single-binding field and is null both when the address is unattached and when
it has more than one member, so a client that reads only that field cannot tell
those two states apart.
A member’s
health reads unknown for instance NICs. It is not a health
check and nothing sets it to anything else on this path — do not build alerting
on it.One address in front of several instances
An address with more than one member is an anycast address, and only an instance pool can own one. Attaching a second interface by hand is refused with409.
The reason is worth understanding before you try to work around it. The members
have to land on different hosts. Two members on the same host means one of them
answers and the other receives nothing at all — and nothing reports it: the
members array lists two, the console shows two, and half your capacity is
silently dark. Nothing on the floating-IP path places instances, so nothing
there can promise the spread. A pool does: it spreads its replicas and keeps the
address’s members in step as it scales.
Tearing it down in the right order
Each of these refusals exists because the step before it was skipped. Working inwards:1
Detach floating IPs from their interfaces
Release refuses while attached, and the default-route delete refuses while
any floating IP in the table’s subnets is live.
2
Delete the routes that target a gateway
Every gateway type refuses detach and delete while a route still references
it.
3
Delete NAT and egress-only gateways
A NAT gateway also blocks the delete of the subnet it lives in.
4
Detach the internet gateway, then delete it
An attached gateway also blocks the VPC delete.
5
Interfaces, then subnets, then the VPC
Detach each interface from its instance first — see
interfaces.