{"record":{"id":"0f62ec54265c576c","repo":"cilium/cilium","slug":"dummy-interface-s-exists-but-could-not-be-read","errorCode":null,"errorMessage":"dummy interface %s exists but could not be read: %w","messagePattern":"dummy interface (.+?) exists but could not be read: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/networkdriver/dummy/dummy.go","lineNumber":132,"sourceCode":"// device of the wrong type.\nfunc (d DummyDevice) Setup(cfg types.DeviceConfig) error {\n\tdummy := &netlink.Dummy{\n\t\tLinkAttrs: netlink.LinkAttrs{Name: d.Name},\n\t}\n\n\terr := netlinkLinkAdd(dummy)\n\tif err == nil {\n\t\treturn nil\n\t}\n\tif !errors.Is(err, unix.EEXIST) {\n\t\treturn fmt.Errorf(\"failed to create dummy interface %s: %w\", d.Name, err)\n\t}\n\n\t// The interface already exists. Adopt it if it is a dummy, otherwise\n\t// replace it.\n\texisting, lookupErr := netlinkLinkByName(d.Name)\n\tif lookupErr != nil {\n\t\treturn fmt.Errorf(\"dummy interface %s exists but could not be read: %w\", d.Name, lookupErr)\n\t}\n\n\tif _, ok := existing.(*netlink.Dummy); ok {\n\t\t// Same type; adopt the existing device.\n\t\treturn nil\n\t}\n\n\t// Stale or mismatched device. Delete and recreate it.\n\tif delErr := netlinkLinkDel(existing); delErr != nil {\n\t\treturn fmt.Errorf(\"failed to delete stale dummy interface %s: %w\", d.Name, delErr)\n\t}\n\tif addErr := netlinkLinkAdd(dummy); addErr != nil {\n\t\treturn fmt.Errorf(\"failed to recreate dummy interface %s: %w\", d.Name, addErr)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/networkdriver/dummy/dummy.go#L114-L150","documentation":"Setup observed EEXIST from LinkAdd, meaning the interface name already exists, but the subsequent netlink.LinkByName lookup of that same interface failed. This is a race/anomaly: the kernel reported the device exists yet it cannot be read back. Setup aborts rather than adopting an unreadable device.","triggerScenarios":"netlinkLinkAdd returns unix.EEXIST, then netlinkLinkByName(d.Name) fails (typically netlink.LinkNotFoundError or a netlink communication error) within the same Setup call.","commonSituations":"A concurrent process deleted the interface between LinkAdd and LinkByName; flaky netlink socket (process netns changed mid-call); rapid pod churn racing two Setups for the same dummyN name.","solutions":["Retry Setup — the race is transient and the next attempt takes a clean path.","Check for other controllers/scripts deleting interfaces named dummy0..dummyN and stop them.","Investigate netlink socket health (netns changes, socket timeouts) in the wrapped error.","Ensure only one actor (the device manager) manages these device names."],"exampleFix":"// before\nif err := dev.Setup(cfg); err != nil { return err }\n// after: tolerate transient races with a bounded retry\nvar err error\nfor i := 0; i < 3; i++ {\n    if err = dev.Setup(cfg); err == nil || !isTransientNetlinkErr(err) { break }\n    time.Sleep(100 * time.Millisecond)\n}","handlingStrategy":"retry","validationCode":"// Pre-check the name is not contended before Setup\nif _, err := safenetlink.LinkByName(dev.Name); err == nil {\n    log.Info(\"interface already exists; Setup will adopt or replace it\")\n}","typeGuard":null,"tryCatchPattern":"if err := dev.Setup(cfg); err != nil {\n    if strings.Contains(err.Error(), \"exists but could not be read\") {\n        time.Sleep(100 * time.Millisecond)\n        return dev.Setup(cfg) // transient race; retry once\n    }\n    return err\n}","preventionTips":["Allow only one controller to manage dummyN device names.","Retry transient netlink races with backoff.","Avoid switching network namespaces in other goroutines during Setup.","Monitor for external scripts/plugins deleting host interfaces."],"tags":["network","netlink","race-condition","cilium"],"backgroundTag":"netlink-link-lookup-failed","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}