netbirdio/netbird · warning
check chain %s: %w
Error message
check chain %s: %w
What it means
Returned by router.cleanUpDefaultForwardRules when iptablesClient.ChainExists(tableNat, NETBIRD-NAT-OUTPUT) errors. This is a query failure, not a chain-presence result: the go-iptables ChainExists call itself could not run (iptables binary/lock/permission problem). It gates removal of the '-j NETBIRD-NAT-OUTPUT' jump from the OUTPUT chain.
Source
Thrown at client/firewall/iptables/router_linux.go:406
}
r.rules = make(map[string][]string)
r.updateState()
return nberrors.FormatErrorOrNil(merr)
}
func (r *router) cleanUpDefaultForwardRules() error {
if err := r.cleanJumpRules(); err != nil {
return fmt.Errorf("clean jump rules: %w", err)
}
log.Debug("flushing routing related tables")
// Remove jump rules from built-in chains before deleting custom chains,
// otherwise the chain deletion fails with "device or resource busy".
if ok, err := r.iptablesClient.ChainExists(tableNat, chainNATOutput); err != nil {
return fmt.Errorf("check chain %s: %w", chainNATOutput, err)
} else if ok {
jumpRule := []string{"-j", chainNATOutput}
if err := r.iptablesClient.Delete(tableNat, "OUTPUT", jumpRule...); err != nil {
log.Debugf("clean OUTPUT jump rule: %v", err)
}
}
for _, chainInfo := range []struct {
chain string
table string
}{
{chainRTFWDIN, tableFilter},
{chainRTFWDOUT, tableFilter},
{chainRTPRE, tableMangle},
{chainRTNAT, tableNat},
{chainRTRDR, tableNat},
{chainNATOutput, tableNat},
{chainRTMSSCLAMP, tableMangle},View on GitHub (pinned to 93e97f4bf1)
Solutions
- Run the probe manually: sudo iptables -t nat -S OUTPUT to reproduce the backend error
- Ensure iptables/nft binaries are installed and on PATH for the daemon
- Free the xtables lock and retry agent start
- Check daemon unit for capability restrictions (needs CAP_NET_ADMIN)
Defensive patterns
Strategy: fallback
Validate before calling
// preflight iptables operability sudo iptables -t nat -S OUTPUT >/dev/null || echo "iptables backend broken"
Try / catch
if ok, err := r.iptablesClient.ChainExists(tableNat, chainNATOutput); err != nil {
// query failure: skip OUTPUT jump cleanup rather than aborting the whole teardown
log.Debugf("check chain %s: %v", chainNATOutput, err)
} else if ok {
_ = r.iptablesClient.Delete(tableNat, "OUTPUT", "-j", chainNATOutput)
} Prevention
- Install iptables/nftables packages in minimal containers
- Keep daemon unit granting CAP_NET_ADMIN
- Probe ChainExists during startup, not only during teardown
When it happens
Trigger: During init cleanup or Reset, the nat-table list operation fails: iptables binary missing from PATH in minimal containers, xtables lock held, CAP_NET_ADMIN lost, or nft backend errors listing the table.
Common situations: Containers with truncated PATH or without the iptables package; agents whose privileges were dropped (systemd RestrictCapabilities); hosts with corrupted nft rulesets.
Related errors
- destroy set %s: %w
- remove nat rule: %w
- remove inverse nat rule: %w
- remove legacy routing rule: %w
- remove legacy forwarding rule %s -> %s: %v
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/97d90ca7546b2610.
Report an issue: GitHub.