Skip to main content
A floating IP is not reachable because you allocated it. Reaching an instance from the internet takes four things, and three of them have nothing to do with the address itself.
Allocating a floating IP and attaching it is not enough. The instance’s subnet also needs an internet gateway attached to the VPC and a 0.0.0.0/0 route pointing at that gateway. Without the route the reply traffic has nowhere to go, and from outside it looks exactly like the inbound packet being dropped — so you spend the afternoon debugging the wrong direction.The API refuses the attach for this reason rather than handing you a dead address.

The reachability chain

1

Attach an internet gateway to the VPC

Attaching creates no routes. It only makes the gateway available as a route target.
2

Add the default route to the subnet's route table

This is what makes the subnet public. It is also what makes the reply path exist.
3

Attach the floating IP to the interface

If the subnet has no default route to an internet gateway, this call fails with 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 called main 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.
Deleting a table refuses in two cases: the main table cannot be deleted at all, and a table still associated with subnets is refused with “reassociate them first”. Routes on a table go away with it.

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 with 409.
The error code on that 409 reads ROUTER_NAME_EXISTS, which is misleading — read the message, which says “destination CIDR already routed in this table”. There is no equal-cost pair and no tie-break between two routes to the same prefix, because the second one never gets created.
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”).
Attaching connects the VPC to the region’s external network. It does not create a route — you still add 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.
There is one per VPC — a second is refused with “target VPC already has a NAT gateway” — and the VPC needs an internet gateway attached first, because the NAT gateway reuses that uplink. Without one the create fails with “target VPC has no internet gateway attached — attach one first”.
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.
Creating a NAT gateway translates nothing. Which subnets it serves follows from the route tables that point at it. Add 0.0.0.0/0 → target_nat_gateway_id to the private subnets’ route table, and they join the moment the route exists.
Its address draws on the same public IPv4 quota as a floating IP — the allowance is one number, not one per feature. 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.
One per VPC, and the VPC must have an IPv6 CIDR (“target VPC has no IPv6 CIDR — an egress-only gateway only routes v6”). It owns no address and does nothing on its own. It becomes effective when a route table points ::/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.
That inbound drop is enforced by the platform and is not something your security groups can open. If you want inbound IPv6 governed by your own rules, route ::/0 at the internet gateway instead.
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 only description and tags — the address is assigned to you:
It counts against the same public IPv4 quota as a NAT gateway address.
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/0 route 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.
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.
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 with 409. 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.
With several members the region’s edge picks one per connection by hashing the connection’s addresses and ports, and every packet of that connection goes to the same one. That spreads connections and survives the loss of a host.
This is not a load balancer. Nothing health-checks what runs inside the instance, and connections in flight to a member that goes away end rather than move. A pool can also carry more replicas than the address has members — a replica sharing a host with an existing member is left out of the set instead of being added and starved.

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.