{"record":{"id":"97d90ca7546b2610","repo":"netbirdio/netbird","slug":"check-chain-s-w","errorCode":null,"errorMessage":"check chain %s: %w","messagePattern":"check chain (.+?): %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"client/firewall/iptables/router_linux.go","lineNumber":406,"sourceCode":"\t}\n\n\tr.rules = make(map[string][]string)\n\tr.updateState()\n\n\treturn nberrors.FormatErrorOrNil(merr)\n}\n\nfunc (r *router) cleanUpDefaultForwardRules() error {\n\tif err := r.cleanJumpRules(); err != nil {\n\t\treturn fmt.Errorf(\"clean jump rules: %w\", err)\n\t}\n\n\tlog.Debug(\"flushing routing related tables\")\n\n\t// Remove jump rules from built-in chains before deleting custom chains,\n\t// otherwise the chain deletion fails with \"device or resource busy\".\n\tif ok, err := r.iptablesClient.ChainExists(tableNat, chainNATOutput); err != nil {\n\t\treturn fmt.Errorf(\"check chain %s: %w\", chainNATOutput, err)\n\t} else if ok {\n\t\tjumpRule := []string{\"-j\", chainNATOutput}\n\t\tif err := r.iptablesClient.Delete(tableNat, \"OUTPUT\", jumpRule...); err != nil {\n\t\t\tlog.Debugf(\"clean OUTPUT jump rule: %v\", err)\n\t\t}\n\t}\n\n\tfor _, chainInfo := range []struct {\n\t\tchain string\n\t\ttable string\n\t}{\n\t\t{chainRTFWDIN, tableFilter},\n\t\t{chainRTFWDOUT, tableFilter},\n\t\t{chainRTPRE, tableMangle},\n\t\t{chainRTNAT, tableNat},\n\t\t{chainRTRDR, tableNat},\n\t\t{chainNATOutput, tableNat},\n\t\t{chainRTMSSCLAMP, tableMangle},","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/firewall/iptables/router_linux.go#L388-L424","documentation":"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.","triggerScenarios":"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.","commonSituations":"Containers with truncated PATH or without the iptables package; agents whose privileges were dropped (systemd RestrictCapabilities); hosts with corrupted nft rulesets.","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)"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// preflight iptables operability\nsudo iptables -t nat -S OUTPUT >/dev/null || echo \"iptables backend broken\"","typeGuard":null,"tryCatchPattern":"if ok, err := r.iptablesClient.ChainExists(tableNat, chainNATOutput); err != nil {\n\t// query failure: skip OUTPUT jump cleanup rather than aborting the whole teardown\n\tlog.Debugf(\"check chain %s: %v\", chainNATOutput, err)\n} else if ok {\n\t_ = r.iptablesClient.Delete(tableNat, \"OUTPUT\", \"-j\", chainNATOutput)\n}","preventionTips":["Install iptables/nftables packages in minimal containers","Keep daemon unit granting CAP_NET_ADMIN","Probe ChainExists during startup, not only during teardown"],"tags":["iptables","cleanup","linux","netbird","diagnostics"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}