netbirdio/netbird · error
list chains: %w
Error message
list chains: %w
What it means
cleanChains could not run ChainExists("mangle", "PREROUTING"). PREROUTING is a built-in chain present whenever the mangle table is loaded, so this error means the iptables invocation itself failed: the iptable_mangle module is not loaded, the process lacks privileges, the binary is missing, or the xtables lock is held. The mangle check guards removal of the NETBIRD-RT-PRE jump and mark rules installed by the router.
Source
Thrown at client/firewall/iptables/acl_linux.go:288
}
for _, rule := range m.entries["FORWARD"] {
err := m.iptablesClient.DeleteIfExists(tableName, "FORWARD", rule...)
if err != nil {
log.Errorf("failed to delete rule: %v, %s", rule, err)
}
}
err = m.iptablesClient.ClearAndDeleteChain(tableName, chainNameInputRules)
if err != nil {
log.Debugf("failed to clear and delete %s chain: %s", chainNameInputRules, err)
return err
}
}
ok, err = m.iptablesClient.ChainExists("mangle", "PREROUTING")
if err != nil {
return fmt.Errorf("list chains: %w", err)
}
if ok {
for _, rule := range m.entries["PREROUTING"] {
err := m.iptablesClient.DeleteIfExists("mangle", "PREROUTING", rule...)
if err != nil {
log.Errorf("failed to delete rule: %v, %s", rule, err)
}
}
}
for _, rule := range m.entries[mangleFwdKey] {
if err := m.iptablesClient.DeleteIfExists(tableMangle, chainFORWARD, rule...); err != nil {
log.Errorf("failed to delete mangle FORWARD guard rule: %v, %s", rule, err)
}
}
for _, ipsetName := range m.ipsetStore.ipsetNames() {
if err := m.flushIPSet(ipsetName); err != nil {View on GitHub (pinned to 93e97f4bf1)
Solutions
- Load the module: `modprobe iptable_mangle` (and ip6table_mangle for v6) or bake it into the kernel/image.
- Confirm root/CAP_NET_ADMIN for the daemon.
- Check `iptables -t mangle -L` succeeds manually in the same context.
- Retry after clearing concurrent iptables users.
Defensive patterns
Strategy: try-catch
Validate before calling
// mangle table must be usable before Reset
out, err := exec.Command("iptables", "-t", "mangle", "-L", "-n").CombinedOutput()
if err != nil {
return fmt.Errorf("mangle table unavailable (modprobe iptable_mangle?): %s", out)
} Try / catch
if err := mgr.Reset(); err != nil {
if strings.Contains(err.Error(), "list chains") {
// table/binary/privilege issue on the mangle table: surface for module loading
log.Errorf("mangle chain listing failed: %v; run modprobe iptable_mangle", err)
}
} Prevention
- Load iptable_mangle (and ip6table_mangle for v6) at boot on modular kernels.
- Include the full netfilter module set in minimal images used for the agent.
- Verify `iptables -t mangle -L` works in the daemon's exact environment before deploying.
- Run as root; chain listing under nft/legacy backends also requires consistent backend selection.
When it happens
Trigger: Reset/cleanChains on kernels where mangle support is modular and unloaded (`modprobe iptable_mangle` fixes it); distroless images without iptables; non-root agents; hosts where another daemon holds the lock during cleanup.
Common situations: Minimal cloud/kernel images with iptable_mangle compiled as module and no auto-load triggered (the filter-table usage earlier does not load mangle); hardened containers; embedded devices with trimmed netfilter.
Related errors
- add IP to ipset: %w
- failed to check rule: %w
- rule already exists
- failed to delete rule: %s, %v: %w
- create router: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/273ca35e72aeed01.
Report an issue: GitHub.