IPv6 on Cloud Providers: Support, Setup and Gotchas
IPv6 gets enabled for cost, reachability or architecture, not idealism. This guide covers the /64 convention, what each provider actually allocates, bringing the address up on an existing server, and the firewall and AAAA mistakes that cause real incidents.

The Practical Reasons to Turn It On
IPv6 rarely gets enabled for idealistic reasons. It gets enabled because of one of three concrete pressures.
The first is cost and scarcity. IPv4 addresses are a finite, allocated resource, and providers increasingly charge for each one attached to an instance. IPv6 blocks are handed out freely because the address space is vast.
The second is reachability. A meaningful and growing share of mobile networks run IPv6-only internally and translate to reach legacy destinations. Serving those clients natively removes a translation layer from the path.
The third is architectural. On IPv6 every instance can hold a globally routable address, which removes the need for network address translation entirely and simplifies anything that hates NAT, such as peer to peer protocols and certain VPN topologies.
None of those forces an all-at-once migration. Dual stack, where a host holds both an IPv4 and an IPv6 address, is the normal state and will be for years.
What Changes in the Address Model
The addresses are longer, written in hexadecimal groups separated by colons, with a run of zero groups compressible to :: once per address. That part is cosmetic. Three structural differences matter more.
A subnet is a /64, almost always. IPv6 convention fixes the host portion at 64 bits, so a /64 is the standard smallest allocation. This is not a shortage: a single /64 holds more addresses than the entire IPv4 internet. Providers typically assign either a /64 or a shorter prefix such as a /56 per account or per network.
An interface holds several addresses at once. A link-local address beginning fe80:: always exists and is used for neighbour discovery. On top of that sit one or more global addresses, and possibly temporary privacy addresses for outbound connections.
There is no broadcast and no ARP. Neighbour Discovery over ICMPv6 replaces both, which has a direct consequence for firewalls covered further down.
The addressing architecture itself is specified in RFC 4291, which is the reference worth keeping open when prefix lengths stop making sense.
How Providers Actually Hand It To You
Support is close to universal now, but the shape of what you receive varies enough to matter.
| Provider | Typical allocation | Notes |
|---|---|---|
| AWS | Prefix per VPC, subnet ranges carved from it | Opt in per VPC; egress-only gateway replaces NAT |
| Azure | Dual stack virtual networks and subnets | Configured on the network, not just the instance |
| Google Cloud | Dual stack subnets, internal or external | Chosen when the subnet is created |
| DigitalOcean | Enabled per Droplet at creation | Cannot be added later on older Droplets in some regions |
| Vultr | Enabled per instance, block assigned | Available in most locations |
| Linode and Akamai | Address per instance, routed ranges on request | Larger ranges available for containers |
| Hetzner Cloud | A range per server | Servers can be ordered without an IPv4 address at all |
| Scaleway and OVHcloud | Per instance, model differs by product line | Check the specific range before designing around it |
The distinction to look for is whether you get one address or a routed range. A single address is enough for a web server. A routed range is what you need if containers or virtual machines on the host should each hold their own address, which is where the developer clouds differ most from each other.
The hyperscaler model treats IPv6 as a property of the network rather than the instance, so enabling it means editing the VPC and its subnets first. The VPC networking article covers those objects, and the AWS guide to adding IPv6 to a VPC walks the specific sequence.
Bringing the Address Up on the Host
When IPv6 is enabled at creation time, current provider images configure it automatically and there is nothing to do. Adding it to an existing server is where the manual work appears.
Start by confirming what the kernel already has:
ip -6 addr show and ip -6 route show
You want a global address on the public interface and a default route via the provider gateway. If the address is present but nothing routes, the default route is missing. If neither is present, the interface configuration needs the address and gateway added, through netplan on Ubuntu or the equivalent file for your distribution.
Then prove the path works end to end, first to an address and then to a name:
ping -6 -c3 2606:4700:4700::1111
curl -6 -sS https://www.google.com -o /dev/null -w '%{http_code}\n'
One provider-specific detail catches people: some assign the gateway on a different prefix than the address, so the route needs an explicit on-link style declaration. If the address looks right and the gateway is unreachable, that is usually why, and the provider documentation such as the Vultr IPv6 configuration guide states the correct form for their network.
The Four Gotchas That Cause Real Incidents
The firewall is a separate ruleset. This is the big one. On Linux, iptables and ip6tables are independent, and a host locked down on IPv4 can be wide open on IPv6 the moment an address appears. Use nftables or a front end like ufw that manages both families together, and verify with ip6tables -L -n. Cloud firewalls have the same split: check whether your provider's rules apply to both families or need separate entries, as the firewalls and security groups guide describes.
Do not block all ICMPv6. IPv4 habits say drop ICMP. On IPv6 that breaks the protocol, because Neighbour Discovery and Path MTU Discovery both ride on ICMPv6. Blocking it produces connections that establish and then hang on the first large packet, which is a miserable thing to debug.
Publishing AAAA too early. Once an AAAA record exists, clients with IPv6 connectivity will prefer it. If the application, the reverse proxy or an upstream dependency is not actually listening on IPv6, those users get timeouts while everyone else sees a working site. Test the address directly before adding the record, and see the DNS setup guide for how long removing it would take to take effect.
Everything downstream logs a new address format. Rate limiters, allow lists, geolocation lookups and abuse tooling that assume a 32-bit address will silently misbehave. Rate limiting in particular should key on a /64 rather than a single IPv6 address, since one client may rotate through many addresses in the same prefix.
Making the Application Stack Listen
Enabling the address does not make services use it. Each listener is configured separately, and the defaults differ by project.
Nginx needs an explicit second listen line, listen [::]:443 ssl; alongside the IPv4 one, since it does not infer dual stack. PostgreSQL and Redis need the address adding to their bind configuration. Docker requires IPv6 to be enabled in the daemon configuration before containers receive addresses at all, and that is a change worth testing outside production first.
Check the result the same way you would for any listener:
ss -ltn | grep -E ':::|\[::\]'
Health checks and monitoring deserve attention too. A check that resolves a name and connects may be using either family, so pin the family explicitly in the check configuration if you want to know that both work. The monitoring guide covers where those checks belong.
If you want somewhere inexpensive to practise the whole sequence, providers that hand out a range per server make it easy. A Vultr account or a Linode account both enable IPv6 at instance creation with no network configuration first, and the Linode and Vultr comparison covers how their networking differs more broadly.
Key Takeaways
- Dual stack is the destination for now. Nothing requires you to drop IPv4.
- A /64 is the normal subnet size, and interfaces legitimately hold several addresses at once.
- Find out whether your provider gives one address or a routed range before designing container networking around it.
- The IPv6 firewall is a separate ruleset. Verify it explicitly, and never block ICMPv6 wholesale.
- Publish an AAAA record only after confirming the whole request path answers over IPv6.
- Configure each listener yourself, then confirm with
ssthat the sockets you expect are bound.
Questions about a cloud account?
Ask about products, variants, availability or purchasing on either channel.



