How to Configure Network Teaming on Fedora Server

Configure network teaming on Fedora Server by installing the `teamd` package and using `nmcli` to define a team device with the desired runner (like activebackup or loadbalance), then attaching physical interfaces as ports.

You have two cables and one server

You installed Fedora Server with two network interfaces. You want the server to stay online if one cable gets yanked or a switch port dies. You tried to find the right tool and saw mentions of bonding, teaming, and nmcli. The documentation feels scattered. You need a setup that survives a single point of failure without manual intervention and persists across reboots.

Network teaming is the modern approach for this on Fedora. It groups physical interfaces into a single logical interface. The configuration is managed by NetworkManager, which writes the profiles to disk so they survive restarts. You define a runner. The runner decides how traffic flows and how the team reacts when a link fails.

What's actually happening

Network teaming moves the logic for link aggregation and failover out of the kernel and into userspace. The kernel sees a virtual interface called team0. It forwards packets to and from this interface just like any other device. The intelligence lives in the teamd daemon.

The daemon communicates with the kernel via netlink. This separation gives you two advantages. You can update the teaming logic without rebooting the kernel. You can change the runner or reload the configuration while the system is running. NetworkManager acts as the controller. It creates the connection profiles, assigns the IP addresses, and ensures the team comes up in the correct order during boot.

Think of the team interface as a virtual switch port. The physical interfaces are cables plugged into that switch. The runner is the policy that decides which cable carries traffic and what happens when a cable breaks. NetworkManager is the technician that wires everything up and writes the configuration to the rack label.

Create the team and attach ports

Install the teamd package first. NetworkManager requires this package to manage team devices. Enable NetworkManager to ensure it is running and will start on boot.

sudo dnf install teamd -y
# WHY: teamd provides the userspace daemon that implements the teaming logic.
# NetworkManager relies on this package to manage team devices.
sudo systemctl enable --now NetworkManager
# WHY: Ensures NetworkManager is running and will start on boot.
# NetworkManager handles the team configuration persistence.

Create the team connection profile. This command defines the logical interface and selects the runner. The activebackup runner provides high availability by switching to a backup link only when the primary fails. This is the safest choice for most servers because it avoids packet reordering issues.

sudo nmcli con add type team con-name team0 ifname team0 team.runner activebackup
# WHY: Creates a team connection profile named team0.
# The activebackup runner switches to the backup port only when the primary fails.

Attach the physical interfaces as slave ports. Replace enp1s0 and enp2s0 with your actual interface names. You can find your interface names by running ip link. NetworkManager will manage these interfaces exclusively once they are attached to the team.

sudo nmcli con add type team-slave con-name team0-port1 ifname enp1s0 master team0
# WHY: Attaches the first physical interface as a slave port.
# Replace enp1s0 with your actual interface name from ip link.
sudo nmcli con add type team-slave con-name team0-port2 ifname enp2s0 master team0
# WHY: Attaches the second physical interface.
# Both ports must be up for the team to function correctly.

Bring up the team connection. NetworkManager activates the master interface and automatically brings up the slave connections. The slaves do not need IP addresses. All traffic flows through the team interface.

sudo nmcli con up team0
# WHY: Activates the team interface and its slave connections.
# NetworkManager brings up the slaves automatically when the master comes up.

Assign a static IP address to the team interface. Modify the connection profile to set the IPv4 method, address, and gateway. Apply the changes by bringing the connection up again.

sudo nmcli con mod team0 ipv4.method manual ipv4.addresses 192.168.1.50/24 ipv4.gateway 192.168.1.1
# WHY: Assigns a static IPv4 address to the logical team interface.
# Traffic flows through team0, not the individual physical ports.
sudo nmcli con mod team0 ipv4.dns "8.8.8.8 8.8.4.4"
# WHY: Sets the DNS servers for the team connection.
# DNS resolution works through the team interface.
sudo nmcli con up team0
# WHY: Re-activates the connection to apply the new IP configuration.
# NetworkManager tears down and rebuilds the interface with the updated settings.

Bring up the team before you assign the IP. The interface must exist before NetworkManager can attach the address.

Verify the team status

Check the team state using teamdctl. This utility queries the teamd daemon directly and returns the current status of the runner and ports. Look for state: up at the top level and link: up for each port.

teamdctl team0 state
# WHY: Queries the teamd daemon for the current state of the team.
# Look for "state: up" and "link: up" for all ports.

The output is a JSON structure. It shows the runner name, the active port, and the health of each link. If a port is down, the JSON will indicate link: down for that port. The runner will automatically switch traffic to the remaining active port in activebackup mode.

Verify the IP configuration on the team interface. The kernel should show the team0 interface with the assigned address. The MAC address usually matches the first active port in activebackup mode.

ip addr show team0
# WHY: Confirms the kernel sees the team interface with the assigned IP.
# The MAC address usually matches the first active port in activebackup mode.
ping -c 4 192.168.1.1
# WHY: Tests connectivity to the gateway through the team interface.
# Successful pings confirm the routing and IP configuration are correct.

Check teamdctl before you check ip addr. The daemon state tells you why the interface is down if the IP is missing.

Common pitfalls and error messages

NetworkManager will refuse to activate a team if a physical interface is already managed by another connection. You will see an error like Error: Connection activation failed: Device 'enp1s0' is already managed by another connection. This happens when you have an existing profile for the physical interface. Delete the old profile before adding the team.

sudo nmcli con delete enp1s0
# WHY: Removes the existing connection profile for the physical interface.
# NetworkManager cannot attach a slave port that has an active profile.

LACP runners require switch configuration. If you use team.runner lacp, your switch must be configured for 802.3ad link aggregation. If the switch is not configured, the LACP negotiation fails and the team interface stays down. The teamdctl output will show link: down for all ports. Check your switch documentation and configure the port channel before enabling LACP on Fedora.

SELinux denials can block teaming in rare cases. NetworkManager handles the labeling automatically for standard interfaces. If you see denials in the logs, check journalctl -t setroubleshoot. The one-line summary usually points to a missing context or a custom script. Do not disable SELinux. Fix the labeling or adjust the policy.

journalctl -xeu NetworkManager
# WHY: Reads the NetworkManager logs with explanatory text.
# The x flag adds explanations and the e flag jumps to the end.
# Look for errors related to teamd or interface activation.

Firewall rules must apply to the team interface. firewalld manages the firewall on Fedora. Assign the team interface to the correct zone and reload the firewall. The runtime configuration and persistent configuration diverge if you skip the reload.

sudo firewall-cmd --permanent --zone=public --add-interface=team0
# WHY: Assigns the team interface to the public zone in the persistent configuration.
# Firewall rules apply to the team interface, not the physical ports.
sudo firewall-cmd --reload
# WHY: Reloads the firewall to apply the persistent configuration.
# Run this after every rule change to keep runtime and persistent configs in sync.

Delete the old connection profile before adding the team. NetworkManager won't let two profiles claim the same interface.

Choose the right runner

Match the runner to your switch configuration and traffic requirements. A mismatched runner causes silent packet loss or flapping links.

Use activebackup when you need high availability and your switch does not support link aggregation. This runner sends traffic through one port and switches to the other only on failure. It is the most compatible option and avoids packet reordering.

Use roundrobin or loadbalance when you want to distribute traffic across all links and your application handles reordering or your switch supports untagged aggregation. These runners increase throughput but require careful testing to ensure your services tolerate out-of-order packets.

Use lacp when your switch supports 802.3ad and you need the switch to negotiate the link state with the server. This runner provides both load balancing and failover. The switch and server must agree on the aggregation group.

Use kernel bonding when you are maintaining legacy infrastructure that predates Fedora 23 or when you require specific offload features only available in the kernel driver. Teaming is the recommended default for new deployments on Fedora.

Match the runner to the switch configuration. A mismatched runner causes silent packet loss or flapping links.

Where to go next