{"record":{"id":"786f631ab7374c46","repo":"cilium/cilium","slug":"failed-to-ensure-local-routing-rule-w","errorCode":null,"errorMessage":"failed to ensure local routing rule: %w","messagePattern":"failed to ensure local routing rule: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/proxy/cell.go","lineNumber":97,"sourceCode":"\tp, err := createProxy(option.Config.EnableL7Proxy, params.Logger, params.LocalNodeStore, params.ProxyPorts, params.EnvoyProxyIntegration, params.DNSProxyIntegration, params.DB, params.Devices, params.RouteManager)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to create proxy: %w\", err)\n\t}\n\n\tif !option.Config.EnableL7Proxy {\n\t\tparams.Logger.Info(\"L7 proxies are disabled\")\n\t\tif option.Config.EnableEnvoyConfig {\n\t\t\tparams.Logger.Warn(\"CiliumEnvoyConfig functionality isn't enabled when L7 proxies are disabled\", logfields.Flag, option.EnableEnvoyConfig)\n\t\t}\n\n\t\treturn p, nil\n\t}\n\n\tif !params.DaemonConfig.DryMode {\n\t\tparams.Lifecycle.Append(cell.Hook{\n\t\t\tOnStart: func(cell.HookContext) error {\n\t\t\t\tif err := linuxdatapath.NodeEnsureLocalRoutingRule(); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"failed to ensure local routing rule: %w\", err)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t},\n\t\t})\n\t}\n\n\tp.proxyPorts.Trigger = job.NewTrigger(job.WithDebounce(10 * time.Second))\n\n\tparams.JobGroup.Add(job.OneShot(\"proxy-ports-restore\", func(ctx context.Context, health cell.Health) error {\n\t\tif err := p.proxyPorts.RestoreProxyPorts(ctx, health); err != nil {\n\t\t\t// report error to health but proceed to start the checkpoint job\n\t\t\thealth.Degraded(\"restore from file failed\", err)\n\t\t}\n\n\t\t// Restore all proxy ports before we register the job to overwrite the file below\n\t\tparams.JobGroup.Add(job.Timer(\"proxy-ports-checkpoint\",\n\t\t\tp.proxyPorts.StoreProxyPorts,\n\t\t\ttime.Minute, /* periodic save in case of I/O errors */","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/proxy/cell.go#L79-L115","documentation":"On cell start (when not in dry mode), the proxy lifecycle hook runs linuxdatapath.NodeEnsureLocalRoutingRule to install the local routing rule that steers proxy return traffic. Failure to program this Linux routing rule aborts startup with this wrapped error.","triggerScenarios":"Agent start (non-dry-mode) where NodeEnsureLocalRoutingRule fails — typically because netlink rules cannot be added: missing CAP_NET_ADMIN, an existing conflicting ip rule with the same priority, or a kernel without rule support.","commonSituations":"Running cilium-agent in a constrained container without NET_ADMIN; hardened hosts blocking ip rule manipulation; leftover stale routing rules from a previous crashed run.","solutions":["Grant the agent CAP_NET_ADMIN and ensure it runs with sufficient privileges (privileged container / host network namespace).","Inspect existing 'ip rule' entries and remove stale/conflicting rules at the Cilium priority.","Verify kernel/netlink support for policy routing on the host.","Use --dry-mode=true for test environments where datapath programming should be skipped."],"exampleFix":"// before: agent without NET_ADMIN fails rule install\ndocker run cilium/cilium-agent   # missing --cap-add NET_ADMIN\n\n// after\ndocker run --cap-add NET_ADMIN cilium/cilium-agent","handlingStrategy":"validation","validationCode":"// Pre-flight on the node: can we add policy routing rules?\n# ip rule add priority 100 lookup local && ip rule del priority 100 || \\\n#   echo \"cannot manipulate ip rules — missing CAP_NET_ADMIN or conflicting rules\"\nip rule show | grep -c 100  # detect pre-existing rule at Cilium's priority","typeGuard":null,"tryCatchPattern":"hook := func(cell.HookContext) error {\n    if err := linuxdatapath.NodeEnsureLocalRoutingRule(); err != nil {\n        if errors.Is(err, os.ErrPermission) {\n            return fmt.Errorf(\"grant NET_ADMIN to the agent: %w\", err)\n        }\n        return fmt.Errorf(\"failed to ensure local routing rule: %w\", err)\n    }\n    return nil\n}","preventionTips":["Run cilium-agent with CAP_NET_ADMIN in a privileged container.","Clean stale 'ip rule' entries from crashed previous runs before restart.","Use --dry-mode in environments without datapath programming rights.","Verify policy-routing kernel support on the host."],"tags":["cilium","linux","routing","netlink","startup"],"backgroundTag":"netlink-operation-not-permitted","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}