$linuxjunkies
>

Configure systemd-networkd

Learn how to configure systemd-networkd with .network unit files for static IPs, DHCP, bonding, bridges, and VLANs on modern Linux servers.

IntermediateUbuntuDebianFedoraArch9 min readUpdated June 7, 2026

Before you start

  • Root or sudo access on the target system
  • systemd version 245 or newer (check with systemctl --version)
  • Physical or SSH console access in case network connectivity is interrupted during the switch
  • Knowledge of your interface names (use 'ip link show' to list them)

systemd-networkd is a lean, dependency-light network daemon that ships with systemd. It excels in server, container, and headless environments where NetworkManager's GUI-centric feature set is unnecessary overhead. This guide shows you how to switch to networkd, write .network unit files, and set up production-ready configurations including bonding, bridges, and VLANs.

NetworkManager vs systemd-networkd

Both daemons configure network interfaces, but they target different use cases:

  • NetworkManager: Designed for desktops and laptops. Handles Wi-Fi roaming, VPN plugins, per-user profiles, and integrates with GNOME/KDE network applets. It is the correct default on Wayland desktops.
  • systemd-networkd: Designed for servers and containers. Static configuration files, no D-Bus GUI dependency, deterministic behaviour on boot, native VLAN/bridge/bond support. Works well alongside systemd-resolved for DNS.

Do not run both daemons managing the same interface simultaneously — pick one per interface, or disable NetworkManager entirely on servers.

Prerequisites

Ensure you have a recent systemd (v245+ covers everything in this guide). Check your version:

systemctl --version

All configuration files go in /etc/systemd/network/. Files in this directory override any matching files in /lib/systemd/network/. Naming convention matters: networkd processes files in lexicographic order, so prefix filenames with two-digit numbers (10-, 20-) to control precedence.

Step 1: Disable NetworkManager, Enable networkd

On Debian/Ubuntu:

sudo systemctl disable --now NetworkManager
sudo systemctl enable --now systemd-networkd
sudo systemctl enable --now systemd-resolved

On Fedora/RHEL/Rocky:

sudo systemctl disable --now NetworkManager
sudo systemctl enable --now systemd-networkd
sudo systemctl enable --now systemd-resolved

On Arch:

sudo systemctl disable --now NetworkManager
sudo systemctl enable --now systemd-networkd systemd-resolved

Point /etc/resolv.conf to the resolved stub resolver (recommended on all distros):

sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

Step 2: Basic Static and DHCP .network Files

Each .network file has at minimum a [Match] section (which interface to configure) and a [Network] section (what to apply). A .netdev file creates virtual devices (bonds, bridges, VLANs); a .network file then configures them.

DHCP on a single interface

sudo tee /etc/systemd/network/10-eth0.network <<'EOF'
[Match]
Name=eth0

[Network]
DHCP=yes
EOF

Static IP address

sudo tee /etc/systemd/network/10-eth0.network <<'EOF'
[Match]
Name=eth0

[Network]
Address=192.168.1.50/24
Gateway=192.168.1.1
DNS=1.1.1.1 9.9.9.9
EOF

Match by MAC address instead of interface name when interface names are unpredictable:

sudo tee /etc/systemd/network/10-server.network <<'EOF'
[Match]
MACAddress=52:54:00:ab:cd:ef

[Network]
Address=10.0.0.10/24
Gateway=10.0.0.1
DNS=10.0.0.1
EOF

Step 3: Network Bonding

Bonding aggregates multiple physical interfaces for redundancy or throughput. You need a .netdev file to create the bond device, then two .network files — one to attach the physical ports as bond members, and one to configure the bond itself.

Create the bond virtual device

sudo tee /etc/systemd/network/20-bond0.netdev <<'EOF'
[NetDev]
Name=bond0
Kind=bond

[Bond]
Mode=active-backup
MIIMonitorSec=100ms
EOF

Common Mode values: active-backup (failover), balance-rr (round-robin), 802.3ad (LACP — requires switch support).

Enslave the physical interfaces

sudo tee /etc/systemd/network/21-bond0-slave.network <<'EOF'
[Match]
Name=eth0 eth1

[Network]
Bond=bond0
EOF

Configure the bond interface

sudo tee /etc/systemd/network/22-bond0.network <<'EOF'
[Match]
Name=bond0

[Network]
Address=192.168.1.50/24
Gateway=192.168.1.1
DNS=1.1.1.1
EOF

Step 4: Network Bridges

Bridges are essential for KVM/QEMU virtual machines that need layer-2 connectivity to the host network. The pattern is identical to bonding: create the bridge device, attach a port, configure the bridge.

Create the bridge device

sudo tee /etc/systemd/network/30-br0.netdev <<'EOF'
[NetDev]
Name=br0
Kind=bridge
EOF

Attach the physical port

sudo tee /etc/systemd/network/31-br0-port.network <<'EOF'
[Match]
Name=eth0

[Network]
Bridge=br0
EOF

Configure the bridge

sudo tee /etc/systemd/network/32-br0.network <<'EOF'
[Match]
Name=br0

[Network]
Address=192.168.1.50/24
Gateway=192.168.1.1
DNS=1.1.1.1
EOF

VMs configured with br0 as their bridge will appear directly on the 192.168.1.0/24 network.

Step 5: VLANs

VLANs require a .netdev to create the VLAN interface, a reference in the parent interface's .network file, and a separate .network file for the VLAN interface itself.

Create the VLAN device

sudo tee /etc/systemd/network/40-vlan100.netdev <<'EOF'
[NetDev]
Name=vlan100
Kind=vlan

[VLAN]
Id=100
EOF

Reference the VLAN in the parent interface

sudo tee /etc/systemd/network/10-eth0.network <<'EOF'
[Match]
Name=eth0

[Network]
VLAN=vlan100
EOF

Configure the VLAN interface

sudo tee /etc/systemd/network/41-vlan100.network <<'EOF'
[Match]
Name=vlan100

[Network]
Address=10.100.0.5/24
Gateway=10.100.0.1
EOF

You can stack VLANs on a bonded or bridged interface by referencing the bond/bridge name in the parent [Match] section instead of a physical interface.

Apply and Verify

Reload networkd after any configuration change:

sudo networkctl reload

Check the status of all managed links:

networkctl status

Inspect a specific interface:

networkctl status eth0

Confirm addresses are applied:

ip addr show
ip route show

For bonding, check which slave is active:

cat /proc/net/bonding/bond0

Troubleshooting

  • Interface shows "unmanaged": networkd only manages interfaces with a matching .network file. Double-check the [Match] section name or MAC. Run networkctl list to see all detected interfaces and their state.
  • "configuring" state that never resolves: Often caused by a missing route or gateway. Check journalctl -u systemd-networkd -f for specific errors.
  • DNS not working after switching: Confirm /etc/resolv.conf is the symlink to the stub resolver, not a plain file left by NetworkManager. Run resolvectl status to verify per-interface DNS assignments.
  • Bond stuck in degraded state: The MIIMonitorSec value controls how fast failures are detected. Also verify both NICs are visible with ip link show before networkd starts.
  • VLAN traffic not passing: Confirm the upstream switch port is configured as a trunk and the correct VLAN IDs are allowed. networkd configures the host correctly; misconfigured switch ports are the most common failure point.
tested on:Ubuntu 24.04Debian 12Fedora 40Arch rolling

Frequently asked questions

Can I run systemd-networkd and NetworkManager on the same machine?
Yes, but not on the same interface simultaneously. It is safest to disable NetworkManager entirely on servers. On desktops with both wired and wireless interfaces, you could configure one with networkd and let NM handle Wi-Fi, but this adds complexity and is generally not recommended.
Do I need to reboot after changing .network files?
No. Run 'sudo networkctl reload' to pick up changes immediately. For .netdev changes (new virtual devices), you may need to run 'sudo systemctl restart systemd-networkd' since virtual devices must be created before they can be configured.
How do I match an interface when its name changes between reboots?
Use MACAddress= in the [Match] section instead of Name=. Alternatively, create a persistent interface name via a systemd .link file in /etc/systemd/network/ using the [Link] Name= key to rename the interface to something stable.
What is the difference between a .network, .netdev, and .link file?
A .link file configures low-level interface properties (renaming, MTU, offloading) and is processed by udev. A .netdev file creates virtual network devices like bonds, bridges, and VLANs. A .network file assigns addressing and routing to any interface, physical or virtual.
How do I configure LACP (802.3ad) bonding instead of active-backup?
In the [Bond] section of your .netdev file, set Mode=802.3ad and optionally set LACPTransmitRate=fast. Your switch ports must also be configured for LACP/port-channel aggregation, or the bond will not come up correctly.

Related guides