{"record":{"id":"cd1fd92f8e81084b","repo":"cilium/cilium","slug":"failed-to-get-loopback-device","errorCode":null,"errorMessage":"failed to get loopback device","messagePattern":"failed to get loopback device","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proxy/routes.go","lineNumber":57,"sourceCode":"// to route packets to and from the L7 proxy. Or removes rules if the proxy is disabled.\nfunc (p *Proxy) ReinstallRoutingRules(ctx context.Context, mtu int, ipsecEnabled, wireguardEnabled bool) error {\n\tdefer p.routeManager.FinalizeInitializer(p.routeInitializer)\n\n\tlocalNode, err := p.localNodeStore.Get(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to retrieve local node: %w\", err)\n\t}\n\n\tfromIngressProxy, fromEgressProxy, mtu := requireFromProxyRoutes(ipsecEnabled, wireguardEnabled, mtu)\n\n\trxn := p.db.ReadTxn()\n\thostDevice, _, hostDeviceFound := p.devices.Get(rxn, tables.DeviceByName(defaults.HostDevice))\n\tciliumNetDevice, _, ciliumNetDeviceFound := p.devices.Get(rxn, tables.DeviceByName(defaults.SecondHostDevice))\n\tlo, _, loFound := p.devices.Get(rxn, tables.DeviceByName(\"lo\"))\n\n\tif option.Config.EnableIPv4 && p.enabled {\n\t\tif !loFound {\n\t\t\treturn fmt.Errorf(\"failed to get loopback device\")\n\t\t}\n\t\tif err := installToProxyRoutesIPv4(lo, p.routeManager, p.routeOwner); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif fromIngressProxy || fromEgressProxy {\n\t\t\tif !hostDeviceFound {\n\t\t\t\treturn fmt.Errorf(\"failed to get host device %s\", defaults.HostDevice)\n\t\t\t}\n\t\t\tinternalIP, _ := netipx.FromStdIP(localNode.GetCiliumInternalIP(false))\n\t\t\tif err := installFromProxyRoutesIPv4(p.routeManager, p.routeOwner, internalIP, hostDevice, fromIngressProxy, fromEgressProxy, mtu); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\tif err := removeFromProxyRulesIPv4(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/proxy/routes.go#L39-L75","documentation":"ReinstallRoutingRules looks up the loopback device ('lo') from the Cilium internal device table before installing the IPv4 to-proxy routes. If the 'lo' device is not present in the table while IPv4 and the proxy are enabled, it refuses to install a default route into the to-proxy table pointing at a nil device and returns this error. It indicates the node's device inventory observed by Cilium is incomplete or not yet populated.","triggerScenarios":"Calling Reinitialize/ReinstallRoutingRules with option.Config.EnableIPv4=true and the proxy enabled while p.devices contains no entry named 'lo' (DeviceByName(\"lo\") lookup misses). This happens during early startup before the device watcher has synced, or if the device table was populated with a restricted device list that excludes loopback.","commonSituations":"Cilium agent starting on a node before netlink device discovery completes; running in environments/containers where 'lo' is missing or renamed; misconfigured --install-no-rules or custom device configuration excluding loopback; DB watchtxn race during agent restart.","solutions":["Ensure the agent has finished device initialization/watch synchronization before calling ReinstallRoutingRules (wait for the devices collection to sync).","Verify 'lo' exists on the host (`ip link show lo`) and that Cilium runs with enough privileges (NET_ADMIN) to observe devices.","Check that no custom device-selection option filters loopback out of the devices table.","Retry Reinitialize after the devices table populates; this is typically transient during startup."],"exampleFix":"// before\nlo, _, loFound := p.devices.Get(rxn, tables.DeviceByName(\"lo\"))\nif !loFound { return fmt.Errorf(\"failed to get loopback device\") }\n// after\n// wait for device synchronization first, then re-run\nif err := p.waitForDevicesSync(ctx); err != nil { return err }\nrxn := p.db.ReadTxn()\nlo, _, loFound := p.devices.Get(rxn, tables.DeviceByName(\"lo\"))\nif !loFound { return fmt.Errorf(\"failed to get loopback device\") }","handlingStrategy":"retry","validationCode":"rxn := p.db.ReadTxn()\nif _, _, ok := p.devices.Get(rxn, tables.DeviceByName(\"lo\")); !ok {\n    return fmt.Errorf(\"loopback device not yet registered; deferring reinstall\")\n}","typeGuard":"func loopbackDeviceReady(devs deviceCache) bool {\n    _, _, ok := devs.Get(devs.ReadTxn(), tables.DeviceByName(\"lo\"))\n    return ok\n}","tryCatchPattern":"if err := p.ReinstallRoutingRules(ctx, mtu, ipsec, wg); err != nil {\n    if strings.Contains(err.Error(), \"failed to get loopback device\") {\n        // transient: schedule retry after device sync\n        return retry.NewError(ctx, true, err)\n    }\n    return err\n}","preventionTips":["Wait for the device watcher/table to signal readiness before reinstalling routing rules","Always run the agent with NET_ADMIN privileges","Verify 'lo' exists on the host before agent startup","Retry Reinitialize with backoff during startup rather than failing hard"],"tags":["network","linux","routing","cilium"],"backgroundTag":"device-not-found","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}