netbirdio/netbird · error
add legacy routing rule: %w
Error message
add legacy routing rule: %w
What it means
Returned by router.AddNatRule when the peer is connected to a pre-route-ACL Management (legacyManagement) and addLegacyRouteRule fails. That path removes any prior rule then appends '-s <src> -d <dst> -j ACCEPT' to NETBIRD-RT-FWD-IN so old management networks keep working. The wrap fires when that append path errors (see error 549 for the inner failure).
Source
Thrown at client/firewall/iptables/router_linux.go:270
return nil
}
func (r *router) deleteIpSet(setName string) error {
if err := r.destroyIPSet(setName); err != nil {
return fmt.Errorf("destroy set %s: %w", setName, err)
}
log.Debugf("Deleted unused ipset %s", setName)
return nil
}
// AddNatRule inserts an iptables rule pair into the nat chain
func (r *router) AddNatRule(pair firewall.RouterPair) error {
if r.legacyManagement {
log.Warnf("This peer is connected to a NetBird Management service with an older version. Allowing all traffic for %s", pair.Destination)
if err := r.addLegacyRouteRule(pair); err != nil {
return fmt.Errorf("add legacy routing rule: %w", err)
}
}
if !pair.Masquerade {
return nil
}
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 nilView on GitHub (pinned to 93e97f4bf1)
Solutions
- Check the agent log for the preceding 'create containers' failure and fix that first
- Confirm the chain exists: sudo iptables -S NETBIRD-RT-FWD-IN (or -L)
- Verify no other process holds the xtables lock (/run/xtables.lock)
- Restart the agent (netbird down/up) so init recreates chains before rules are added
Defensive patterns
Strategy: validation
Validate before calling
// ensure the chain exists before the legacy append
if ok, err := iptablesClient.ChainExists(tableFilter, chainRTFWDIN); err != nil {
return fmt.Errorf("check chain: %w", err)
} else if !ok {
return fmt.Errorf("chain %s missing; re-run init", chainRTFWDIN)
} Prevention
- Treat init/createContainers failures as fatal before applying rules
- Upgrade management past the route-ACL era so legacy mode is never entered
- Do not flush NETBIRD chains manually while connected to old management
When it happens
Trigger: AddNatRule(pair) with r.legacyManagement set via SetLegacyManagement after the login/legacy check. Fails when the NETBIRD-RT-FWD-IN chain does not exist because init/createContainers failed earlier, the iptables backend errors (binary missing, xtables lock held), or privileges were dropped.
Common situations: Peer managed by an old NetBird management (< route ACL era) on a host where the custom chains were flushed manually or by a crashed prior run; hosts with mixed iptables-legacy/nft backends; SELinux/AppArmor denying iptables execution.
Related errors
- remove legacy routing rule: %w
- add legacy forwarding rule %s -> %s: %v
- remove legacy forwarding rule %s -> %s: %v
- remove legacy forwarding rule: %v
- add IP to ipset: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/4a09fe36da8c64ac.
Report an issue: GitHub.