{"record":{"id":"0c3bb8f211fcdbf0","repo":"netbirdio/netbird","slug":"add-nat-prerouting-jump-rule-v","errorCode":null,"errorMessage":"add nat prerouting jump rule: %v","messagePattern":"add nat prerouting jump rule: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/firewall/iptables/router_linux.go","lineNumber":626,"sourceCode":"func (r *router) addJumpRules() error {\n\t// Jump to nat chain\n\tnatRule := []string{\"-j\", chainRTNAT}\n\tif err := r.iptablesClient.Insert(tableNat, chainPOSTROUTING, 1, natRule...); err != nil {\n\t\treturn fmt.Errorf(\"add nat postrouting jump rule: %v\", err)\n\t}\n\tr.rules[jumpNatPost] = natRule\n\n\t// Jump to mangle prerouting chain\n\tpreRule := []string{\"-j\", chainRTPRE}\n\tif err := r.iptablesClient.Insert(tableMangle, chainPREROUTING, 1, preRule...); err != nil {\n\t\treturn fmt.Errorf(\"add mangle prerouting jump rule: %v\", err)\n\t}\n\tr.rules[jumpManglePre] = preRule\n\n\t// Jump to nat prerouting chain\n\trdrRule := []string{\"-j\", chainRTRDR}\n\tif err := r.iptablesClient.Insert(tableNat, chainPREROUTING, 1, rdrRule...); err != nil {\n\t\treturn fmt.Errorf(\"add nat prerouting jump rule: %v\", err)\n\t}\n\tr.rules[jumpNatPre] = rdrRule\n\n\treturn nil\n}\n\nfunc (r *router) cleanJumpRules() error {\n\tfor _, ruleKey := range []string{jumpNatPost, jumpManglePre, jumpNatPre, jumpMSSClamp} {\n\t\tif rule, exists := r.rules[ruleKey]; exists {\n\t\t\tvar table, chain string\n\t\t\tswitch ruleKey {\n\t\t\tcase jumpNatPost:\n\t\t\t\ttable = tableNat\n\t\t\t\tchain = chainPOSTROUTING\n\t\t\tcase jumpManglePre:\n\t\t\t\ttable = tableMangle\n\t\t\t\tchain = chainPREROUTING\n\t\t\tcase jumpNatPre:","sourceCodeStart":608,"sourceCodeEnd":644,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/firewall/iptables/router_linux.go#L608-L644","documentation":"Third insert in addJumpRules(): `-j NETBIRD-RT-RDR` at position 1 of nat PREROUTING, directing inbound traffic into NetBird's redirect/DNAT chain. As with the sibling jump rules, the error propagates as 'add jump rules' and aborts router container setup, and the two jump rules inserted before it may remain in place until the next cleanup.","triggerScenarios":"`iptables -t nat -I PREROUTING 1 -j NETBIRD-RT-RDR` failing on missing iptable_nat, missing CAP_NET_ADMIN, held xtables lock, or external deletion of the NETBIRD-RT-RDR chain between its creation and this insert.","commonSituations":"Same family as the other two jump-rule errors: stripped kernels, containers, lock contention, legacy/nft mismatch. Frequently the v6 instance fails first on hosts where ip6table_nat is not loaded even though IPv4 NAT works.","solutions":["Reproduce manually: `sudo iptables -t nat -I PREROUTING 1 -j NETBIRD-RT-RDR`","`modprobe iptable_nat` / `modprobe ip6table_nat`","Check that NETBIRD-RT-RDR exists in `iptables -t nat -S` and recreate with -N if a cleanup half-finished","Verify daemon runs as root and no other process holds /run/xtables.lock","Run `netbird down` to remove the partially applied sibling jumps, then `netbird up`"],"exampleFix":"// before\nif err := r.iptablesClient.Insert(tableNat, chainPREROUTING, 1, rdrRule...); err != nil {\n    return fmt.Errorf(\"add nat prerouting jump rule: %v\", err)\n}\n\n// after: clean up earlier jumps on failure so setup stays atomic\nif err := r.iptablesClient.Insert(tableNat, chainPREROUTING, 1, rdrRule...); err != nil {\n    if ok, _ := r.iptablesClient.ChainExists(tableNat, chainPOSTROUTING); ok {\n        _ = r.iptablesClient.DeleteIfExists(tableNat, chainPOSTROUTING, natRule...)\n        delete(r.rules, jumpNatPost)\n    }\n    return fmt.Errorf(\"add nat prerouting jump rule: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"func rdrChainExists(ipt *iptables.IPTables) bool {\n    ok, err := ipt.ChainExists(\"nat\", \"NETBIRD-RT-RDR\")\n    return err == nil && ok\n}","typeGuard":null,"tryCatchPattern":"Catch at the createContainers boundary and roll back the two earlier jump-rule inserts before returning, preserving the built-in chains' original state.","preventionTips":["modprobe iptable_nat for both address families","Prevent external deletion of NETBIRD-RT-RDR during operation","Run netbird down before host-level nat table surgery"],"tags":["network","linux","iptables","nat","dnat"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}