netbirdio/netbird · error
failed to insert established rule: %v
Error message
failed to insert established rule: %v
What it means
insertEstablishedRule() puts `-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT` at position 1 of NETBIRD-RT-FWD-IN / NETBIRD-RT-FWD-OUT (filter table) so replies to routed flows are not dropped by later filtering rules. Wrapped by createContainers() as 'insert established rule', its failure aborts router init and routed traffic would break even if setup continued.
Source
Thrown at client/firewall/iptables/router_linux.go:599
"-p", "tcp",
"--tcp-flags", "SYN,RST", "SYN",
"-j", "TCPMSS",
"--set-mss", fmt.Sprintf("%d", mss),
}
if err := r.iptablesClient.Append(tableMangle, chainRTMSSCLAMP, ruleOut...); err != nil {
return fmt.Errorf("add outbound MSS clamp rule: %w", err)
}
r.rules["mss-clamp-out"] = ruleOut
return nil
}
func (r *router) insertEstablishedRule(chain string) error {
establishedRule := getConntrackEstablished()
err := r.iptablesClient.Insert(tableFilter, chain, 1, establishedRule...)
if err != nil {
return fmt.Errorf("failed to insert established rule: %v", err)
}
ruleKey := "established-" + chain
r.rules[ruleKey] = establishedRule
return nil
}
func (r *router) addJumpRules() error {
// Jump to nat chain
natRule := []string{"-j", chainRTNAT}
if err := r.iptablesClient.Insert(tableNat, chainPOSTROUTING, 1, natRule...); err != nil {
return fmt.Errorf("add nat postrouting jump rule: %v", err)
}
r.rules[jumpNatPost] = natRule
// Jump to mangle prerouting chain
preRule := []string{"-j", chainRTPRE}View on GitHub (pinned to 93e97f4bf1)
Solutions
- Run the insert by hand to see stderr: `sudo iptables -t filter -I NETBIRD-RT-FWD-IN 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT`
- `modprobe xt_conntrack ip_conntrack`
- Check `sudo iptables -S | grep NETBIRD-RT-FWD` for chains deleted by other tooling and stop that tooling
- Confirm root/CAP_NET_ADMIN for the daemon
- Retry `netbird up`; createContainers recreates chains and reruns the insert
Example fix
// before
err := r.iptablesClient.Insert(tableFilter, chain, 1, establishedRule...)
if err != nil {
return fmt.Errorf("failed to insert established rule: %v", err)
}
// after: self-heal a vanished chain before inserting
if ok, _ := r.iptablesClient.ChainExists(tableFilter, chain); !ok {
if err := r.iptablesClient.NewChain(tableFilter, chain); err != nil {
return fmt.Errorf("recreate chain %s: %w", chain, err)
}
}
if err := r.iptablesClient.Insert(tableFilter, chain, 1, establishedRule...); err != nil {
return fmt.Errorf("insert established rule into %s: %w", chain, err)
} Defensive patterns
Strategy: validation
Validate before calling
func conntrackMatchSupported(ipt *iptables.IPTables) error {
probe := []string{"-m", "conntrack", "--ctstate", "ESTABLISHED", "-j", "ACCEPT"}
if err := ipt.Append("filter", "FORWARD", probe...); err != nil {
return err
}
return ipt.DeleteIfExists("filter", "FORWARD", probe...)
} Try / catch
Return the error from createContainers so routing fails loudly rather than shipping a router that drops reply traffic; no partial continuation.
Prevention
- modprobe xt_conntrack and ensure nf_conntrack is loaded
- Stop third-party tools from deleting NETBIRD-* chains
- Treat any 'insert established rule' log line as routing-down and alert
When it happens
Trigger: `iptables -t filter -I NETBIRD-RT-FWD-IN 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT` failing when xt_conntrack is unavailable, the filter table is inaccessible, CAP_NET_ADMIN is missing, or the chain NETBIRD-RT-FWD-IN was deleted by external tooling between chain creation and this insert.
Common situations: Hosts without conntrack match support (rare, custom kernels); 'security' tooling or a second NetBird instance deleting NETBIRD-* chains mid-setup; containers where the filter table is read-only; fresh minimal systems where the conntrack module loads lazily and the first iptables call races module loading.
Related errors
- add jump rules: %w
- add mangle prerouting rule: %w
- add mangle postrouting rule: %w
- add nat postrouting jump rule: %v
- add mangle prerouting jump rule: %v
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/9b8c1d4aa23cdd68.
Report an issue: GitHub.