{"record":{"id":"470b24c6249981c6","repo":"netbirdio/netbird","slug":"determine-routing-w","errorCode":null,"errorMessage":"determine routing: %w","messagePattern":"determine routing: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/firewall/uspfilter/filter.go","lineNumber":1760,"sourceCode":"\n// SetTCPPacketHook sets the outbound TCP packet hook. Pass nil hook to remove.\nfunc (m *Manager) SetTCPPacketHook(ip netip.Addr, dPort uint16, hook func(packet []byte) bool) {\n\tcommon.SetHook(&m.tcpHookOut, ip, dPort, hook)\n}\n\n// SetLogLevel sets the log level for the firewall manager\nfunc (m *Manager) SetLogLevel(level log.Level) {\n\tif m.logger != nil {\n\t\tm.logger.SetLevel(nblog.Level(level))\n\t}\n}\n\nfunc (m *Manager) EnableRouting() error {\n\tm.mutex.Lock()\n\tdefer m.mutex.Unlock()\n\n\tif err := m.determineRouting(); err != nil {\n\t\treturn fmt.Errorf(\"determine routing: %w\", err)\n\t}\n\n\tif m.forwarder.Load() == nil {\n\t\treturn nil\n\t}\n\n\trules, err := m.blockInvalidRouted(m.wgIface)\n\t// Persist whatever was installed even on partial failure, so DisableRouting\n\t// can clean it up later.\n\tm.blockRules = rules\n\tif err != nil {\n\t\treturn fmt.Errorf(\"block invalid routed: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (m *Manager) DisableRouting() error {","sourceCodeStart":1742,"sourceCodeEnd":1778,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/firewall/uspfilter/filter.go#L1742-L1778","documentation":"Returned by Manager.EnableRouting (client/firewall/uspfilter/filter.go:1760) wrapping determineRouting. determineRouting parses EnvDisableUserspaceRouting / EnvForceUserspaceRouter (parse failures only warn) then switches to a routing mode; the only error paths are initForwarder's: 'forwarding not supported' when wgIface.GetWGDevice() is nil, or 'create forwarder: %w'. So this error means the chosen mode demands userspace routing but the device cannot support it, or forwarder construction failed.","triggerScenarios":"EnableRouting in kernel WireGuard mode where GetWGDevice() returns nil (the default branch selects userspace routing when nativeFirewall is nil or netstack is on); forceUserspaceRouter set via env on a kernel-mode interface; netstack mode with forwarder.New failing as in error 754.","commonSituations":"Miscombined env flags (forcing userspace routing on kernel mode); platforms where nativeFirewall detection fails so default falls into userspace routing; embedded netstack builds.","solutions":["If the interface is kernel-mode, provide a native firewall or set EnvDisableUserspaceRouting so the switch takes the disable branch","Ensure GetWGDevice() is populated before EnableRouting (userspace device fully constructed)","Fix the underlying forwarder.New failure (valid address/MTU) when the device exists but construction fails","Check the wrapped message to distinguish 'forwarding not supported' (mode problem) from 'create forwarder' (setup problem)"],"exampleFix":"// before\nif err := m.determineRouting(); err != nil {\n    return fmt.Errorf(\"determine routing: %w\", err)\n}\n// after\nif err := m.determineRouting(); err != nil {\n    if errors.Is(err, errForwardingNotSupported) && m.wgIface.GetWGDevice() == nil {\n        log.Info(\"kernel device without userspace routing support; routing disabled\")\n        return nil\n    }\n    return fmt.Errorf(\"determine routing: %w\", err)\n}","handlingStrategy":"fallback","validationCode":"// Choose routing mode explicitly instead of relying on device probing\nif wgIface.GetWGDevice() == nil && nativeFirewall == nil {\n    os.Setenv(EnvDisableUserspaceRouting, \"true\")\n}","typeGuard":"func canRouteUserspace(wg common.IFaceMapper) bool {\n    return wg.GetWGDevice() != nil\n}","tryCatchPattern":"if err := fw.EnableRouting(); err != nil {\n    if strings.Contains(err.Error(), \"forwarding not supported\") {\n        log.Info(\"userspace forwarding unavailable on this device; routing off\")\n        return nil\n    }\n    return err\n}","preventionTips":["Set NB env flags deliberately; verify bool spelling (strconv.ParseBool values) since parse errors only warn and fall through to defaults","Probe GetWGDevice before enabling routing in mixed-mode deployments","Log which determineRouting branch fired so mode selection is auditable"],"tags":["uspfilter","routing","configuration","env-flags"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}