{"record":{"id":"0f93059141ec0683","repo":"netbirdio/netbird","slug":"delete-route-rule-w","errorCode":null,"errorMessage":"delete route rule: %w","messagePattern":"delete route rule: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"client/internal/acl/manager.go","lineNumber":229,"sourceCode":"\t// Apply new rules - firewall manager will return existing rule ID if already present\n\tfor _, rule := range rules {\n\t\tid, err := d.applyRouteACL(rule, dynamicResolver)\n\t\tif err != nil {\n\t\t\tif errors.Is(err, ErrSourceRangesEmpty) {\n\t\t\t\tlog.Debugf(\"skipping empty sources rule with destination %s: %v\", rule.Destination, err)\n\t\t\t} else {\n\t\t\t\tmerr = multierror.Append(merr, fmt.Errorf(\"add route rule: %w\", err))\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tnewRouteRules[id] = struct{}{}\n\t}\n\n\t// Clean up old firewall rules\n\tfor id := range d.routeRules {\n\t\tif _, exists := newRouteRules[id]; !exists {\n\t\t\tif err := d.firewall.DeleteRouteRule(id); err != nil {\n\t\t\t\tmerr = multierror.Append(merr, fmt.Errorf(\"delete route rule: %w\", err))\n\t\t\t}\n\t\t\t// implicitly deleted from the map\n\t\t}\n\t}\n\n\td.routeRules = newRouteRules\n\treturn nberrors.FormatErrorOrNil(merr)\n}\n\nfunc (d *DefaultManager) applyRouteACL(rule *mgmProto.RouteFirewallRule, dynamicResolver bool) (id.RuleID, error) {\n\tif len(rule.SourceRanges) == 0 {\n\t\treturn \"\", ErrSourceRangesEmpty\n\t}\n\n\tvar sources []netip.Prefix\n\tfor _, sourceRange := range rule.SourceRanges {\n\t\tsource, err := netip.ParsePrefix(sourceRange)\n\t\tif err != nil {","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/internal/acl/manager.go#L211-L247","documentation":"Appended in applyRouteACLs when firewall.DeleteRouteRule(id) fails while removing route ACL rules that disappeared from the new network map. The manager reconciles d.routeRules against newRouteRules after every update; a delete failure means the backend no longer has the rule under that ID or cannot remove it - e.g. the ruleset was flushed externally, the nftables/iptables table was replaced, or the rule was already garbage-collected by a backend restart.","triggerScenarios":"External `nft flush ruleset` / `iptables -F` while the agent runs; another NetBird instance or firewall tool (firewalld, ufw reload) rewriting tables; agent's backend manager re-initialized between updates losing rule handles.","commonSituations":"Operators manually flushing firewall rules on a host; concurrent firewall management tools; container images recreating network namespaces. Stale rules then linger or the map and backend diverge until the next full reconcile.","solutions":["Avoid flushing or editing NetBird's firewall chains externally; let the agent own its ruleset","Restart the agent (or trigger a full reconnect) so it reconciles from scratch - the manager rebuilds route rules from the network map","If it recurs, check for a second netbird instance or firewall daemon (firewalld/ufw) fighting over the tables"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := d.firewall.DeleteRouteRule(id); err != nil {\n    if isRuleNotFoundError(err) { // backend reports it is already gone\n        log.Debugf(\"route rule %s already absent: %v\", id, err)\n    } else {\n        merr = multierror.Append(merr, fmt.Errorf(\"delete route rule: %w\", err))\n    }\n}","preventionTips":["Never flush or edit the agent's firewall tables externally; use the management API to change policies","Run one agent and disable competing firewall daemons on NetBird-managed hosts","After any manual firewall intervention, restart the agent so it reconciles its rule maps from scratch"],"tags":["go","netbird","acl","firewall","reconciliation","cleanup"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}