cilium/cilium · error
unable to lookup link %d: %w
Error message
unable to lookup link %d: %w
What it means
After the netns section succeeds, the plugin (now back in the host netns) resolves the host-side veth by the peer index captured inside the container: netlink.LinkByIndex(peerIndex). If the link cannot be found, this error wraps it. It means the container-side veth's peer is no longer visible from the host, so the plugin cannot learn the host veth name/MAC/index required for the Cilium EndpointChangeRequest.
Source
Thrown at plugins/cilium-cni/chaining/generic-veth/generic-veth.go:180
if rt.MTU != int(pluginCtx.CiliumConf.RouteMTU) {
rt.MTU = int(pluginCtx.CiliumConf.RouteMTU)
err = netlink.RouteReplace(&rt)
if err != nil {
err = fmt.Errorf("unable to replace the mtu %d for the route %s: %s", rt.MTU, rt.String(), err.Error())
return err
}
}
}
}
return nil
}); err != nil {
return
}
peer, err = netlink.LinkByIndex(peerIndex)
if err != nil {
err = fmt.Errorf("unable to lookup link %d: %w", peerIndex, err)
return
}
hostMac, _ = mac.FromHardwareAddr(peer.Attrs().HardwareAddr)
vethHostName = peer.Attrs().Name
vethHostIdx = peer.Attrs().Index
switch {
case vethHostName == "":
err = errors.New("unable to determine name of veth pair on the host side")
return
case !hostMac.IsValid():
err = errors.New("unable to determine MAC address of veth pair on the host side")
return
case !vethLXCMac.IsValid():
err = errors.New("unable to determine MAC address of veth pair on the container side")
return
case vethIP == "" && vethIPv6 == "":View on GitHub (pinned to ac7b90affa)
Solutions
- Retry pod creation — a teardown race resolves itself; check whether the pod's sandbox was being stopped at the same time.
- Verify the peer ifindex still exists on the host: ip link | grep <ifindex> and compare with the error's %d value.
- Check node memory/netlink health (dmesg for rtnetlink errors); reboot if persistent rtnetlink corruption is seen.
- Ensure the runtime isn't concurrently modifying the veth pair (check containerd/CRI logs for the same container ID).
Defensive patterns
Strategy: retry
Try / catch
peer, err := netlink.LinkByIndex(peerIndex)
if err != nil {
if errors.Is(err, syscall.ENODEV) {
// host-side peer gone: sandbox teardown race, kubelet will retry
}
return fmt.Errorf("unable to lookup link %d: %w", peerIndex, err)
} Prevention
- Check whether the sandbox was being stopped when the error occurred; treat those as transient.
- Correlate containerd/CRI logs with CNI failure timestamps to detect teardown races.
- Keep the kernel updated; long-running nodes can accumulate rtnetlink issues.
- Confirm no hardened runtime is restricting host netlink access for the CNI plugin.
When it happens
Trigger: netlink.LinkByIndex(peerIndex) in Add() (host netns) returns an error: the peer veth was deleted between VethPeerIndex() inside the container and this lookup (pod teardown race), a stale/incorrect peerIndex, or a netlink dump failure on the host.
Common situations: Kubelet deleting the sandbox while CNI ADD is in flight; move-to-netns operations that destroyed the peer; kernel/netlink bugs after long uptime; running the plugin in an environment where host netlink is restricted (某些 hardened runtimes).
Related errors
- unable to determine name of veth pair on the host side
- unable to determine index interface of veth pair on the host
- link %s is not a veth interface
- unable to retrieve index of veth peer %s: %w
- unable to determine MAC address of veth pair on the host sid
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/8f95634403120b89.
Report an issue: GitHub.