{"record":{"id":"4ec0f160e5c0b5d6","repo":"cilium/cilium","slug":"deleting-outdated-geneve-device-w","errorCode":null,"errorMessage":"deleting outdated geneve device: %w","messagePattern":"deleting outdated geneve device: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/datapath/loader/netlink.go","lineNumber":262,"sourceCode":"\t\t\tHardwareAddr: mac.HardwareAddr(),\n\t\t},\n\t\tFlowBased: true,\n\t\tDport:     dport,\n\t\tPortLow:   int(srcPortLow),\n\t\tPortHigh:  int(srcPortHigh),\n\t}\n\n\tl, err := ensureDevice(logger, sysctl, dev)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"creating geneve device: %w\", err)\n\t}\n\n\t// Recreate the device with the correct destination port. Modifying the device\n\t// without recreating it is not supported.\n\tgeneve, _ := l.(*netlink.Geneve)\n\tif geneve.Dport != dport {\n\t\tif err := netlink.LinkDel(l); err != nil {\n\t\t\treturn fmt.Errorf(\"deleting outdated geneve device: %w\", err)\n\t\t}\n\t\tif _, err := ensureDevice(logger, sysctl, dev); err != nil {\n\t\t\treturn fmt.Errorf(\"recreating geneve device %s: %w\", defaults.GeneveDevice, err)\n\t\t}\n\t}\n\tif geneve.PortLow != int(srcPortLow) || geneve.PortHigh != int(srcPortHigh) {\n\t\tlogger.Info(\n\t\t\t\"Source port range hint ignored given geneve device already exists\",\n\t\t\tlogfields.Hint, fmt.Sprintf(\"(%d-%d)\", int(srcPortLow), int(srcPortHigh)),\n\t\t\tlogfields.Range, fmt.Sprintf(\"(%d-%d)\", geneve.PortLow, geneve.PortHigh),\n\t\t\tlogfields.Device, defaults.GeneveDevice,\n\t\t)\n\t}\n\treturn nil\n}\n\n// setupVxlanDevice ensures the cilium_vxlan device is created with the given\n// port, source port range, and MTU.","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/datapath/loader/netlink.go#L244-L280","documentation":"The Geneve device cannot be modified in place to change its destination port, so Cilium deletes the existing cilium_geneve and recreates it. If netlink.LinkDel fails it wraps with 'deleting outdated geneve device'. This occurs only when the existing device's Dport differs from the configured one.","triggerScenarios":"geneve-destination-port (default 6081) changed at runtime; existing cilium_geneve has an old Dport; netlink LinkDel on it fails (busy, EPERM, netlink error).","commonSituations":"Rolling config change of tunnel-destination-port across a cluster; mixed-version nodes with different ports; device held busy during live migration/restart windows.","solutions":["Ensure the agent has CAP_NET_ADMIN to delete links","Manually delete: ip link del cilium_geneve, then restart the agent so it recreates with the new port","Keep tunnel-destination-port consistent cluster-wide to avoid repeated recreation","Check for processes/sockets keeping the device busy (lsof, ip -d link show cilium_geneve)"],"exampleFix":"// before\nError: deleting outdated geneve device: device is busy\n// after\nip link del cilium_geneve\nsystemctl restart cilium  # recreated with configured dport","handlingStrategy":"retry","validationCode":"// Keep tunnel-destination-port stable cluster-wide; before changing it:\n//   ip -d link show cilium_geneve  # inspect current dport\n//   ip link del cilium_geneve 2>/dev/null || true","typeGuard":null,"tryCatchPattern":"err := setupTunnelDevice(...)\nif err != nil && strings.Contains(err.Error(), \"deleting outdated geneve\") {\n    time.Sleep(2 * time.Second)\n    err = setupTunnelDevice(...) // retry once after kernel cleanup\n}","preventionTips":["Change destination ports only during maintenance windows","Roll configs gradually across nodes","Grant CAP_NET_ADMIN","Verify no process holds the device during recreation"],"tags":["cilium","netlink","geneve","device-recreation"],"backgroundTag":"netlink-device-removal-failed","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}