netbirdio/netbird · error
remove legacy forwarding rule: %v
Error message
remove legacy forwarding rule: %v
What it means
Accumulated by router.RemoveAllLegacyRouteRules when iptablesClient.DeleteIfExists fails for any rule whose key starts with the ForwardingFormat prefix. Unlike the per-rule paths, this sweeps all legacy rules and collects failures in a go-multierror, deleting only the map entries whose kernel delete succeeded. Leftover failures mean permissive '-j ACCEPT' forwarding rules survive.
Source
Thrown at client/firewall/iptables/router_linux.go:365
// GetLegacyManagement returns the current legacy management mode
func (r *router) GetLegacyManagement() bool {
return r.legacyManagement
}
// SetLegacyManagement sets the route manager to use legacy management mode
func (r *router) SetLegacyManagement(isLegacy bool) {
r.legacyManagement = isLegacy
}
// RemoveAllLegacyRouteRules removes all legacy routing rules for mgmt servers pre route acls
func (r *router) RemoveAllLegacyRouteRules() error {
var merr *multierror.Error
for k, rule := range r.rules {
if !strings.HasPrefix(k, firewall.ForwardingFormatPrefix) {
continue
}
if err := r.iptablesClient.DeleteIfExists(tableFilter, chainRTFWDIN, rule...); err != nil {
merr = multierror.Append(merr, fmt.Errorf("remove legacy forwarding rule: %v", err))
} else {
delete(r.rules, k)
}
}
r.updateState()
return nberrors.FormatErrorOrNil(merr)
}
func (r *router) Reset() error {
var merr *multierror.Error
if err := r.cleanUpDefaultForwardRules(); err != nil {
merr = multierror.Append(merr, err)
}
if err := r.ipsetCounter.Flush(); err != nil {
merr = multierror.Append(merr, err)View on GitHub (pinned to 93e97f4bf1)
Solutions
- After the failure, list leftovers: sudo iptables -S NETBIRD-RT-FWD-IN and delete each ACCEPT rule manually
- Retry RemoveAllLegacyRouteRules (idempotent: DeleteIfExists skips absent rules)
- Restart the agent and immediately run down/up to resynchronize state
- Check the multierror body to see which specific rule specs failed
Defensive patterns
Strategy: fallback
Try / catch
if err := r.RemoveAllLegacyRouteRules(); err != nil {
// fall back to a manual sweep so no permissive ACCEPT rules survive
log.Warnf("automatic legacy sweep incomplete: %v; verify NETBIRD-RT-FWD-IN", err)
} Prevention
- After a failed sweep always inspect 'iptables -S NETBIRD-RT-FWD-IN' for -j ACCEPT leftovers
- Treat surviving legacy ACCEPT rules as a security issue and remove them manually
- Retry the sweep; it is idempotent
When it happens
Trigger: Called when disconnecting from a legacy management or transitioning to route ACLs: iterates r.rules, deletes each legacy forwarding spec from NETBIRD-RT-FWD-IN. Fails per rule on iptables invocation errors (lock, backend, missing chain handled as success by DeleteIfExists only when the rule is absent).
Common situations: netbird down after chains were partially flushed manually; iptables backend changed mid-session; host under heavy parallel firewall churn.
Related errors
- remove legacy routing rule: %w
- remove legacy forwarding rule %s -> %s: %v
- destroy set %s: %w
- add legacy routing rule: %w
- remove nat rule: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/a5a82c60d7772a97.
Report an issue: GitHub.