netbirdio/netbird · error
remove nat rule: %w
Error message
remove nat rule: %w
What it means
Returned by router.RemoveNatRule when removeNatRule(pair) fails. It looks up the rule spec stored under GenKey(NatFormat, pair) and calls DeleteIfExists on the NETBIRD-RT-PRE mangle chain, then decrements the ipset refcounter. The wrap fires on the DeleteIfExists error; failure aborts before updateState, leaving the in-memory map consistent but the rule possibly still in the chain.
Source
Thrown at client/firewall/iptables/router_linux.go:295
if err := r.addNatRule(pair); err != nil {
return fmt.Errorf("add nat rule: %w", err)
}
if err := r.addNatRule(firewall.GetInversePair(pair)); err != nil {
return fmt.Errorf("add inverse nat rule: %w", err)
}
r.updateState()
return nil
}
// RemoveNatRule removes an iptables rule pair from forwarding and nat chains
func (r *router) RemoveNatRule(pair firewall.RouterPair) error {
if pair.Masquerade {
if err := r.removeNatRule(pair); err != nil {
return fmt.Errorf("remove nat rule: %w", err)
}
if err := r.removeNatRule(firewall.GetInversePair(pair)); err != nil {
return fmt.Errorf("remove inverse nat rule: %w", err)
}
}
if err := r.removeLegacyRouteRule(pair); err != nil {
return fmt.Errorf("remove legacy routing rule: %w", err)
}
r.updateState()
return nil
}
// addLegacyRouteRule adds a legacy routing rule for mgmt servers pre route acls
func (r *router) addLegacyRouteRule(pair firewall.RouterPair) error {View on GitHub (pinned to 93e97f4bf1)
Solutions
- Retry removal after a short delay (lock contention is transient)
- Verify leftover marks: sudo iptables -t mangle -S NETBIRD-RT-PRE and delete stragglers manually if needed
- Keep one iptables backend; restart the agent after switching legacy/nft
- Re-run 'sudo netbird down' to drive full teardown
Defensive patterns
Strategy: retry
Try / catch
if err := r.removeNatRule(pair); err != nil {
// DeleteIfExists is idempotent; transient lock errors clear on retry
return fmt.Errorf("remove nat rule: %w", err)
} Prevention
- Do not switch iptables legacy/nft alternatives while the daemon runs
- Complete teardown with 'netbird down' rather than killing the process
- Check for leftover MARK rules after failed removals
When it happens
Trigger: Removing a masqueraded route/exit-node pair (netbird down, route update, management push). DeleteIfExists rarely fails: xtables lock contention, iptables binary swapped between legacy/nft backends mid-run, or security modules denying exec.
Common situations: Host where iptables was switched from legacy to nft backend (update-alternatives) after agent start; heavy parallel iptables activity by config management (puppet/ansible firewall modules).
Related errors
- remove inverse nat rule: %w
- remove v4 NAT rule: %w
- remove v6 NAT rule: %w
- destroy set %s: %w
- add nat rule: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/0f7d6aefa29ec99a.
Report an issue: GitHub.