WESERVER / KNOWLEDGE BASE

How to configure IPv6 on an Ubuntu server with netplan

On Ubuntu, a static IPv6 address goes into the netplan file with its prefix and a ::/0 route, is tested with netplan try and made permanent with netplan apply. File example, on-link and common errors.

Short answer

On Ubuntu, a persistent IPv6 address is defined in the YAML file under /etc/netplan/: put the address with its prefix length in an addresses line under the network interface, add the gateway in a routes entry with ::/0 as the destination, test the change with netplan try and make it permanent with netplan apply. Then use ip -6 addr and ping -6 to confirm the address is up and outbound traffic works.

The commands are the same on Ubuntu 20.04, 22.04 and 24.04 server; all three manage networking through netplan. The examples use the 2001:db8::/32 block reserved for documentation (RFC 3849): server address 2001:db8:1234:5678::10/64, gateway 2001:db8:1234:5678::1, interface eth0. On your own server, replace them with the address, prefix and gateway your provider gave you.

What information do you need before you start?

You need three things: the IPv6 address or block assigned to you, the prefix length and the gateway address. WeServer VDS instances come with both IPv4 and IPv6; on IPv6 Subnet VDS the first three plans include a /64 and the higher plans a /48 or /64 block. If the gateway is missing from your delivery details, ask the support team rather than guessing. With the wrong gateway the address shows up on the interface, but the server cannot reach anything outside.

Connect over SSH as root or as a user with sudo rights. Use IPv4 for that session if you can, since an IPv6 session may drop while you change IPv6 settings. If your provider offers console access, find it before you start; it is how you get back in after a bad network change.

Where is the netplan file and how do you find the interface name?

ls /etc/netplan/ lists the configuration files. On servers built from cloud images this is usually 50-cloud-init.yaml; manual installs may have 00-installer-config.yaml or 01-netcfg.yaml instead. Find the interface name with ip -br link: the line other than lo that shows UP, for example eth0, ens3 or enp1s0, is the interface connected to the outside network.

If the file is 50-cloud-init.yaml, read the comment at the top. cloud-init may rewrite this file on reboot, and the IPv6 lines you added will be gone. To prevent that, create /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg containing network: {config: disabled}. Back up the existing file before editing it: cp /etc/netplan/50-cloud-init.yaml /root/50-cloud-init.yaml.bak.

How do you write a netplan file for a static IPv6 address?

Open the existing file with nano or vim and add the IPv6 settings under the same interface. Defining the interface again in a second file leads to surprises that depend on merge order, and a single file is easier to follow. YAML is indentation-sensitive: never use tabs, only spaces. On a server that gets IPv4 over DHCP, the finished file looks like this line by line (the number in brackets is how many spaces start the line):

  • network: (0)
  • version: 2 (2)
  • ethernets: (2)
  • eth0: (4)
  • dhcp4: true (6)
  • addresses: (6)
  • - "2001:db8:1234:5678::10/64" (8)
  • routes: (6)
  • - to: "::/0" (8)
  • via: "2001:db8:1234:5678::1" (10)
  • nameservers: (6)
  • addresses: ["2001:4860:4860::8888", "2606:4700:4700::1111"] (8)

What do the lines do, and why should you avoid gateway6?

The addresses list holds the addresses to add to the interface, each with its prefix length. Quote the address. Values with colons usually work unquoted, but quoting removes any chance of YAML reading the value the wrong way. If IPv4 is set statically on the server, its address sits in the same list; add the IPv6 address as a new line.

The ::/0 route under routes tells the system which gateway all IPv6 traffic leaves through. The gateway6 key you will see in older guides was deprecated in the netplan versions shipped with Ubuntu 22.04. It is still read, but netplan prints a warning every time it runs, so use the routes form on new setups.

The nameservers block is optional. If the server already resolves DNS over IPv4, you can reach IPv6 addresses without it. The two addresses in the example are public DNS resolvers; if your provider recommends a DNS address, use that one.

How do you apply the change without losing your SSH session?

After saving the file, work through these steps:

  • Run chmod 600 /etc/netplan/50-cloud-init.yaml so only root can read the file. Otherwise newer netplan versions warn that “Permissions … are too open”.
  • Check the file with netplan generate. No output means the syntax is fine; errors are reported with line and column numbers.
  • Apply the settings temporarily with netplan try. It waits 120 seconds and rolls back to the old configuration unless you press Enter. During that window, confirm from a second terminal that you can still connect, then press Enter to keep the change.
  • In some setups netplan try reports that it cannot roll back. In that case run netplan apply, but make sure you have console access first.

What if the gateway is outside your subnet?

On some networks the gateway sits outside the prefix assigned to the server. For example, the address is given as a /128, or the gateway lives in a different /64. The kernel then has no idea how to reach the gateway and the route is not added; if you try adding it by hand with ip -6 route add, you get “Nexthop has invalid gateway”.

The fix is to add on-link: true to the route entry, aligned with the via line. It tells the kernel the gateway is on the same physical link. A link-local gateway such as fe80::1 does not need on-link, because link-local addresses are always on the interface’s own link. Check which case matches your network against the details from your provider.

How do you add several IPv6 addresses from your block?

If you need a few addresses, list each one on its own line under addresses, for example 2001:db8:1234:5678::11/64 and 2001:db8:1234:5678::12/64, then apply with netplan try. That is enough for giving separate sites or services on a web server their own IPv6 address.

For hundreds or thousands of addresses, writing them all into netplan is impractical, and every address adds neighbour discovery (NDP) traffic. At that scale, confirm with your provider whether the block is routed to your server or delivered on-link, because the right approach depends on it. The difference between /48 and /64 and how prefixes work are covered in the article on what an IPv6 subnet is.

How do you check that the IPv6 configuration works?

  • ip -6 addr show dev eth0: your address should appear with scope global. If it says tentative or dadfailed, something is wrong; see the error list below.
  • ip -6 route show default: you should see a line like default via 2001:db8:1234:5678::1 dev eth0.
  • ping -6 -c 4 2606:4700:4700::1111: tests outbound IPv6 without depending on DNS.
  • curl -6 -sI https://example.com: if an HTTP status line comes back, AAAA lookups work and web connections over IPv6 go through.
  • From another machine, confirm the server is reachable from outside with ssh -6 user@2001:db8:1234:5678::10 or ping -6.

Netplan IPv6 errors and how to fix them

  • netplan generate says “Invalid YAML” or “inconsistent indentation”. Cause: a tab character or misaligned spaces. Fix: go to the line in the error message and indent it with spaces, aligned with other lines at the same level.
  • ping -6 returns “connect: Network is unreachable”. Cause: there is no IPv6 default route. Fix: check the routes block and the ::/0 line; if ip -6 route show default is empty, the gateway was never added.
  • The address is on the interface but ping fails with “Destination unreachable: Address unreachable”. Cause: the gateway address is wrong or outside the prefix. Fix: compare the gateway with your provider’s details and add on-link: true if it is outside the prefix.
  • ip -6 addr shows dadfailed on the address. Cause: another device on the network already uses the same address. Fix: pick a different address from your block; if it keeps happening, tell your provider.
  • The interface has no IPv6 address at all, not even one starting with fe80. Cause: IPv6 is disabled on the system. Fix: if sysctl net.ipv6.conf.all.disable_ipv6 prints 1, remove the matching line from /etc/sysctl.conf or /etc/sysctl.d/ and run sysctl --system; if the GRUB command line contains ipv6.disable=1, remove it, run update-grub and reboot.
  • The IPv6 address disappeared after a reboot. Cause: cloud-init rewrote the netplan file. Fix: add the 99-disable-network-config.cfg file and write the IPv6 lines again.

Frequently asked questions

Can I use DHCPv6 or autoconfiguration instead of a static address? If your network sends router advertisements or offers DHCPv6, dhcp6: true can pick up an address automatically. A static definition is more predictable on a server, where you want to know exactly which address is in use. Ask your provider which method the network supports.

Will netplan apply drop my SSH connection? If you only added IPv6 lines, a session opened over IPv4 usually stays up. A mistake in the IPv4 settings can cut the connection, which is why starting with netplan try and keeping console access ready is the safer route.

Do Debian and AlmaLinux use netplan too? Depending on the image, Debian uses either ifupdown (/etc/network/interfaces) or netplan; if /etc/netplan is empty, the settings live in ifupdown. AlmaLinux and Rocky Linux manage networking with NetworkManager, where you set the IPv6 address with nmcli.

Does enabling IPv6 change the firewall setup? With IPV6=yes in /etc/default/ufw, ufw applies its rules to IPv6 as well. If you write your own ip6tables rules, do not block ICMPv6 wholesale; neighbour discovery runs over ICMPv6, and without it IPv6 connectivity never comes up. The guide to first security steps on a new VDS has the details.

Should I write the address as /64 or /128? Use the prefix length your provider gave you. If the block was assigned as a /64, define the address with /64, and no extra settings are needed when the gateway is in the same block. With /128 the gateway falls outside the prefix and you need on-link: true.

Browse related productsAsk on WhatsApp← Back to category

RELATED

Related articles

ALL IN WE1

Let’s build your infrastructure.

Share your requirements and we will help you choose the right resources and server type.

Talk on WhatsApp