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 nil

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Check the agent log for the preceding 'create containers' failure and fix that first
  2. Confirm the chain exists: sudo iptables -S NETBIRD-RT-FWD-IN (or -L)
  3. Verify no other process holds the xtables lock (/run/xtables.lock)
  4. 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

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


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/4a09fe36da8c64ac. Report an issue: GitHub.