netbirdio/netbird · warning

check chain %s in table %s: %w

Error message

check chain %s in table %s: %w

What it means

Returned by router.cleanUpDefaultForwardRules inside its loop over the seven NetBird custom chains (NETBIRD-RT-FWD-IN/OUT in filter, NETBIRD-RT-PRE and NETBIRD-RT-MSSCLAMP in mangle, NETBIRD-RT-NAT/RDR/NAT-OUTPUT in nat) when iptablesClient.ChainExists errors for one of them. Like error 554 this is a failed query about the chain, not the chain being absent (absent returns ok=false and is skipped).

Source

Thrown at client/firewall/iptables/router_linux.go:428

			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},
	} {
		ok, err := r.iptablesClient.ChainExists(chainInfo.table, chainInfo.chain)
		if err != nil {
			return fmt.Errorf("check chain %s in table %s: %w", chainInfo.chain, chainInfo.table, err)
		} else if ok {
			if err = r.iptablesClient.ClearAndDeleteChain(chainInfo.table, chainInfo.chain); err != nil {
				return fmt.Errorf("clear and delete chain %s in table %s: %w", chainInfo.chain, chainInfo.table, err)
			}
		}
	}

	return nil
}

func (r *router) createContainers() error {
	for _, chainInfo := range []struct {
		chain string
		table string
	}{
		{chainRTFWDIN, tableFilter},
		{chainRTFWDOUT, tableFilter},
		{chainRTPRE, tableMangle},

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Reproduce per table: sudo iptables -S; sudo iptables -t nat -S; sudo iptables -t mangle -S
  2. Install/verify iptables + conntrack/nft packages in containers
  3. Load table support (modprobe iptable_nat iptable_mangle iptable_filter) or enable in kernel config
  4. Retry agent start once lock contention clears
Defensive patterns

Strategy: fallback

Validate before calling

# verify every table the manager touches is listable
for t in filter nat mangle; do sudo iptables -t $t -S >/dev/null || echo "table $t broken"; done

Try / catch

ok, err := r.iptablesClient.ChainExists(chainInfo.table, chainInfo.chain)
if err != nil {
	// record and continue: a broken query on one table should not skip the rest
	merr = multierror.Append(merr, fmt.Errorf("check chain %s in table %s: %w", chainInfo.chain, chainInfo.table, err))
	continue
}

Prevention

When it happens

Trigger: Init cleanup or Reset iterating the chain list; the ChainExists lookup on one table/chain fails because the iptables binary cannot execute or list that table (missing kernel table support, lock, permissions).

Common situations: Minimal kernels without nat/mangle table support (some containers, WSL1-era); iptables-nft with a broken ruleset; lock contention with other firewall tooling during startup.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/22fdfe3d828cf8e4. Report an issue: GitHub.