Libvirt on Arch Linux and Manjaro defaults to using iptables for managing virtual network firewall rules. If your system runs nftables (the default on modern Arch), libvirt fails with “Failed to initialize a valid firewall backend” when starting virtual networks. This happens because libvirt cannot find the legacy iptables binary it expects.
This guide covers multiple ways to fix this error – from installing the iptables compatibility layer to configuring libvirt to use nftables directly. The steps work on Arch Linux, Manjaro, EndeavourOS, and other Arch-based distributions.
Step 1: Understand the Error
The full error typically looks like this when starting a virtual network or launching libvirtd:
error: Failed to start network default
error: internal error: Failed to initialize a valid firewall backend
You may also see it in the libvirtd journal logs:
journalctl -u libvirtd --no-pager -n 20
Look for lines containing “firewall backend” in the output:
libvirtd[1234]: Failed to initialize a valid firewall backend
Arch Linux switched from iptables to nftables as the default firewall framework. However, libvirt still expects iptables binaries to manage NAT rules for virtual networks. When those binaries are missing or the wrong iptables variant is installed, libvirt cannot set up the firewall rules needed for VM networking.
Step 2: Install iptables-nft Compatibility Layer
The cleanest fix is installing iptables-nft, which provides iptables commands that translate to nftables rules under the hood. This gives libvirt the iptables interface it needs while keeping your system on nftables. You also need dnsmasq (for DHCP/DNS on virtual networks) and dmidecode.
sudo pacman -S iptables-nft dnsmasq dmidecode
If you already have the legacy iptables package installed, pacman will ask to replace it. Confirm the replacement – iptables-nft is a drop-in replacement that works with nftables.
Verify that the iptables binary now points to the nft variant:
iptables --version
The output should show nf_tables as the backend:
iptables v1.8.10 (nf_tables)
Step 3: Enable and Start libvirtd
With the firewall backend now available, restart the libvirt daemon to pick up the changes. If you are setting up KVM on Arch Linux / Manjaro for the first time, enable the service so it starts on boot.
sudo systemctl enable --now libvirtd
If libvirtd was already running, restart it instead:
sudo systemctl restart libvirtd
Check that the service is running without errors:
systemctl status libvirtd
The output should show active (running) with no firewall backend errors:
● libvirtd.service - Virtualization daemon
Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; preset: disabled)
Active: active (running)
Main PID: 2345 (libvirtd)
Step 4: Verify Virtual Networks Work
The real test is whether libvirt can start virtual networks. List all configured networks first:
sudo virsh net-list --all
You should see the default network (and any custom networks you have configured):
Name State Autostart Persistent
----------------------------------------------
default inactive yes yes
Start the default network:
sudo virsh net-start default
A successful start confirms the firewall backend is working:
Network default started
Set the default network to start automatically on boot:
sudo virsh net-autostart default
Confirm the network autostart is set:
Network default marked as autostarted
If you use virt-manager, close it and reopen it. The connection should work without firewall backend errors now.
Step 5: Alternative – Configure libvirt to Use nftables Directly
If you prefer not to install any iptables compatibility packages, you can configure libvirt to use nftables as its firewall backend directly. This approach is cleaner for systems that are fully committed to nftables.
Edit the libvirt network configuration:
sudo vi /etc/libvirt/network.conf
Add or update the firewall backend setting:
firewall_backend = "nftables"
Then restart libvirtd to apply the change:
sudo systemctl restart libvirtd
Verify by starting a virtual network as shown in Step 4. Note that the nftables backend requires libvirt 9.0 or later. Check your version with:
libvirtd --version
Arch Linux ships libvirt 10.x+ in its repositories, so the nftables backend is fully supported.
Step 6: Fix for firewalld Users
If you run firewalld on your Arch system, libvirt should detect it automatically and use the firewalld backend instead of raw iptables. When this detection fails, the same error appears.
Make sure firewalld is running before libvirtd starts:
sudo systemctl enable --now firewalld
Verify the libvirt zone exists in firewalld:
sudo firewall-cmd --get-zones
The output should include a libvirt zone among the listed zones. If the libvirt zone is missing, create it:
sudo firewall-cmd --permanent --new-zone=libvirt
sudo firewall-cmd --reload
Then restart libvirtd:
sudo systemctl restart libvirtd
Step 7: Troubleshoot Persistent Issues
If the error persists after the steps above, check these common causes.
dnsmasq conflicts
Libvirt starts its own dnsmasq instance for each virtual network. If a system-level dnsmasq is already running and binding to the same interfaces, the libvirt dnsmasq fails silently. Check for running dnsmasq processes:
ps aux | grep dnsmasq
If you see a non-libvirt dnsmasq running, stop and disable it:
sudo systemctl stop dnsmasq
sudo systemctl disable dnsmasq
Then restart libvirtd and try starting the network again.
Bridge interface issues
Virtual networks need the virbr0 bridge interface. If it was not created or got removed, recreate the default network. First, destroy any broken network definition:
sudo virsh net-destroy default
sudo virsh net-undefine default
Then redefine and start it from the default template:
sudo virsh net-define /usr/share/libvirt/networks/default.xml
sudo virsh net-start default
sudo virsh net-autostart default
Verify the bridge interface was created:
ip link show virbr0
The output should show the virbr0 interface in UP state:
4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT
link/ether 52:54:00:xx:xx:xx brd ff:ff:ff:ff:ff:ff
The state shows DOWN until a VM connects to the network – that is normal. For custom bridge networking on Arch Linux, you can define additional bridge interfaces for your VMs.
Kernel module not loaded
The nf_tables or ip_tables kernel module must be loaded for either backend to work. Check and load them if needed:
lsmod | grep nf_tables
If no output is returned, load the module manually:
sudo modprobe nf_tables
To make the module load on every boot:
echo "nf_tables" | sudo tee /etc/modules-load.d/nftables.conf
Conclusion
The “Failed to initialize a valid firewall backend” error comes down to libvirt not finding the firewall tools it needs. Installing iptables-nft is the quickest fix, while switching the firewall backend to nftables in /etc/libvirt/network.conf is the cleaner long-term solution for Arch-based systems. Either way, verify your setup by starting a virtual network and confirming VMs can reach the outside network through NAT.
That’s worked for me on Manjaro 21.
Good article.