Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild

How to Set a Static IP on Ubuntu Server with Netplan

Sean

Platform Writer

Jul 06, 2026
7 min read

To set a static IP on Ubuntu Server, write a netplan YAML file in /etc/netplan/ with dhcp4: no and an addresses: block, then run sudo netplan apply. The YAML is the source of truth. The renderer underneath (networkd or NetworkManager) generates the actual config from it. The team that gets the YAML right has the static IP. The team that does not is debugging why the box is unreachable.

How to Set a Static IP on Ubuntu Server with Netplan

Table of contents

The netplan config file

Netplan has been the default network configuration tool on Ubuntu Server since 17.10. The config lives in /etc/netplan/*.yaml. The default file on a fresh install is 00-installer-config.yaml or 50-cloud-init.yaml on cloud images. The numbering matters — files are applied in lexical order, and a later file overrides an earlier one.

The right config for a static IP looks like this:

network:
  version: 2
  renderer: networkd
  ethernets:
    enp0s3:
      dhcp4: no
      addresses:
        - 192.168.1.100/24
      routes:
        - to: default
          via: 192.168.1.1
      nameservers:
        addresses:
          - 1.1.1.1
          - 8.8.8.8

Replace enp0s3 with the actual interface name (ip a to find it). Replace 192.168.1.100/24 with the static IP and CIDR. Replace 192.168.1.1 with the gateway. Replace the nameservers with whatever you want to use. The /24 is the CIDR; for most home and office networks it is correct. For a /23 or /16, adjust accordingly.

On Ubuntu Desktop the renderer is NetworkManager, not networkd. The YAML is the same. Netplan detects the renderer from the existing configuration. If you are switching renderers, add the renderer: networkd or renderer: NetworkManager line explicitly.

Applying the config safely

The right way to apply the config is sudo netplan try. This is the version of netplan apply that reverts automatically after 120 seconds if the new config breaks connectivity. On a remote box, that 120-second window is the difference between a recoverable mistake and a reinstall. The flow is:

sudo nano /etc/netplan/00-installer-config.yaml
sudo netplan try

If the new config works (you can still ping, the new IP responds), confirm by pressing Enter. If it does not, wait 120 seconds and the old config comes back automatically.

For production boxes where the network is not on a fast path back to the operator (a single home IP behind NAT, a hosting provider’s KVM, a private VLAN), the right answer is netplan try and a screen session that auto-confirms after 60 seconds. The screen approach looks like this:

screen sudo netplan try

Then in the netplan output, type Y to confirm. If the screen session drops because SSH drops, netplan reverts. If the screen session holds because the new IP works, the operator’s next SSH lands on the new IP. This is the pattern that works for remote boxes where you do not have out-of-band console access.

Common mistakes and what they cause

The most common mistake is the indentation. Netplan YAML is whitespace-sensitive, and a single misplaced space causes netplan apply to fail with a parse error. The right indentation is two spaces per level, with no tabs. The most common spot for a wrong indent is the addresses: block under a network interface — the items in the list should be indented four spaces from the interface name, not six.

The second most common mistake is leaving dhcp4: yes while also specifying addresses:. Netplan will take the static address, but the routing and nameserver config will come from DHCP, which usually produces a working but confusing result. The right answer is dhcp4: no on a static config.

The third most common mistake is using a CIDR that does not match the network. A /24 on a /23 network produces a working local subnet but a broken gateway. Run ipcalc (or any CIDR calculator) before you write the YAML if you are not 100% sure of the network layout. The right format is 192.168.1.100/24 — IP, slash, prefix length. The prefix length is the number of leading bits in the netmask. /24 is 255.255.255.0. /16 is 255.255.0.0.

Cloud-init override on cloud images

On AWS, GCP, Azure, and most other cloud providers, the Ubuntu Server image ships with a 50-cloud-init.yaml file that is regenerated on every boot. The right way to set a static IP on a cloud image is not to edit the YAML by hand — the next boot will overwrite your changes. The right way is to disable the cloud-init network config:

echo 'network: {config: disabled}' > /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg

After that, the cloud-init YAML is ignored and your netplan file is the source of truth. On a cloud server, this is rarely what you want — the cloud provider’s DHCP is usually the right answer. But for special cases (an internal subnet with a private IP, a multi-NIC box with a static IP on the second interface), this is the right pattern.

Verifying the new IP is actually working

After netplan apply, verify three things. The first is the IP:

ip a show enp0s3

The interface should show the new IP in the inet line. The second is the default route:

ip route

The default route should be through the gateway you specified. The third is DNS resolution:

resolvectl status

The DNS servers should be the ones you specified. If any of the three is wrong, the netplan config did not apply correctly. The most likely cause is a YAML parse error — sudo netplan --debug generate shows you the generated config files in /run/systemd/network/ and is the right tool to debug.

A common case where the apply looks fine but the network is broken is the wrong CIDR. The interface gets the IP, the route looks right, but traffic leaves the wrong interface. The fix is to verify the CIDR matches the actual subnet. ipcalc 192.168.1.100/24 shows you the network, broadcast, and usable range.

Why not just edit /etc/network/interfaces?

Ubuntu Server 18.04+ uses netplan by default. The /etc/network/interfaces file is still there as a fallback for the ifupdown package, but on a netplan-managed system it is ignored. The legacy ifupdown approach was:

auto enp0s3
iface enp0s3 inet static
  address 192.168.1.100/24
  gateway 192.168.1.1
  dns-nameservers 1.1.1.1 8.8.8.8

The netplan YAML is more verbose, but the structure is the same. The reason for the migration was that netplan generates configs for both networkd and NetworkManager from the same source of truth, which means the same YAML works on a server with networkd and on a desktop with NetworkManager. The trade-off is a learning curve and a YAML parser that is stricter than the legacy format.

FAQ

Why does netplan try not work on my system?

The most common cause is that the system is using NetworkManager instead of networkd. netplan try calls a system reboot if the apply breaks, but NetworkManager is harder to roll back. The fix is to add renderer: networkd to the YAML and disable NetworkManager for the interface. On a server, the right answer is almost always networkd; NetworkManager is a desktop thing.

My static IP works but I cannot reach the internet. What is wrong?

The most common cause is the default route. Check ip route and look for a default via <gateway> line. If it is missing or points to the wrong gateway, traffic to the internet never gets a path. The fix is to add the routes: block to the YAML with the right via: address.

Can I have multiple IPs on one interface?

Yes. Add them to the addresses: list:

addresses:
  - 192.168.1.100/24
  - 192.168.1.101/24

Each address needs to be in the same subnet or in different subnets with the right routing. The right pattern for a multi-IP box is one primary and the rest as aliases.

What is the difference between networkd and NetworkManager?

networkd is systemd’s network configuration daemon. It runs without a user session and is the right answer for servers. NetworkManager is a userspace daemon that handles roaming, VPNs, and WiFi. It is the right answer for desktops. Netplan generates configs for whichever one is active. On Ubuntu Server, networkd is the default. On Ubuntu Desktop, NetworkManager is the default.

How do I see what netplan would do without applying it?

Run sudo netplan --debug generate. It prints the generated config files in /run/systemd/network/ without applying them. The right answer for a debugging session is to look at the generated file and see if it matches your intent.

What about IPv6?

Netplan handles IPv6 the same way. Replace dhcp4 with dhcp6, add addresses: with the IPv6 prefix, and specify gateway6 in the routes block. Most modern setups use SLAAC for IPv6, which means dhcp6: yes and no manual address. The right answer for a server that needs a stable IPv6 is to set it manually; the right answer for a workstation is to let SLAAC handle it.

If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.

Useful related references:

#ubuntu#guide#dev-infra#tutorial