cilium/cilium · error
updating tcx program: %w
Error message
updating tcx program: %w
What it means
upsertTCXProgram wraps errors from updateTCX that are neither successful updates nor os.ErrNotExist (missing/defunct pin). Such an error means an existing pinned tcx link could not be inspected or updated, so the upsert aborts instead of attaching a new link.
Source
Thrown at pkg/datapath/loader/tcx.go:44
case netlink.HANDLE_MIN_INGRESS:
return ebpf.AttachTCXIngress
case netlink.HANDLE_MIN_EGRESS:
return ebpf.AttachTCXEgress
}
panic(fmt.Sprintf("invalid tc direction: %d", parent))
}
// upsertTCXProgram updates or creates a new tcx attachment for prog to device.
// Returns [link.ErrNotSupported] if tcx is not supported on the node.
func upsertTCXProgram(logger *slog.Logger, device netlink.Link, prog *ebpf.Program, progName, bpffsDir string, parent uint32) error {
err := updateTCX(logger, prog, progName, bpffsDir)
if err == nil {
// Link was updated, nothing left to do.
return nil
}
if !errors.Is(err, os.ErrNotExist) {
// Unrecoverable error, surface to the caller.
return fmt.Errorf("updating tcx program: %w", err)
}
return attachTCX(logger, device, prog, progName, bpffsDir, parentToAttachType(parent))
}
// attachTCX creates a new tcx attachment for prog to device at the given attach
// type. It pins the resulting link object to progName in bpffsDir.
//
// progName is typically the Program's key in CollectionSpec.Programs.
func attachTCX(logger *slog.Logger, device netlink.Link, prog *ebpf.Program, progName, bpffsDir string, attach ebpf.AttachType) error {
if err := bpf.MkdirBPF(bpffsDir); err != nil {
return fmt.Errorf("creating bpffs link dir for tcx attachment to device %s: %w", device.Attrs().Name, err)
}
l, err := link.AttachTCX(link.TCXOptions{
Program: prog,
Attach: attach,
Interface: device.Attrs().Index,View on GitHub (pinned to ac7b90affa)
Solutions
- Inspect the pin: bpftool link show pinned <bpffsDir>/<progName>; remove a corrupt pin and restart the agent.
- Verify bpffs is mounted correctly and writable, and the agent holds CAP_SYS_ADMIN.
- If the pin path changed (config/env), align the bpffs directory configuration with what is on disk.
- As a fallback, disable tcx (run with legacy tc) if the kernel cannot support tcx links.
Example fix
// before: corrupt pin breaks update $ bpftool link show pinned /sys/fs/bpf/cilium/tcx_from_netdev Error: can't get link info // after $ rm /sys/fs/bpf/cilium/tcx_from_netdev && cilium-agent restart
Defensive patterns
Strategy: try-catch
Validate before calling
// Probe the pin before upsert
if _, err := os.Stat(filepath.Join(bpffsDir, progName)); err == nil {
if _, err := link.LoadPinnedLink(filepath.Join(bpffsDir, progName), nil); err != nil {
os.Remove(filepath.Join(bpffsDir, progName)) // corrupt pin
}
} Try / catch
if err := upsertTCXProgram(logger, device, prog, progName, bpffsDir, parent); err != nil {
if !errors.Is(err, link.ErrNotSupported) && !errors.Is(err, os.ErrNotExist) {
logger.Error("tcx update failed", "pin", filepath.Join(bpffsDir, progName), "err", err)
os.Remove(filepath.Join(bpffsDir, progName)) // drop corrupt pin and retry
}
return err
} Prevention
- Validate bpffs integrity at agent startup.
- Keep the bpffs directory config consistent across restarts.
- Ensure CAP_SYS_ADMIN for link operations.
- Clean pins left by previous Cilium versions.
When it happens
Trigger: attachSKBProgram with tcxEnabled calls upsertTCXProgram; bpf.UpdateLink on bpffsDir/progName fails with something other than ENOLINK or ErrNotExist — e.g. pin path is a corrupt file, bpffs I/O error, or permission denied opening the pinned link.
Common situations: Corrupted bpffs state after node crash, bpffs mount mismatch between restarts, permission/capability loss, wrong pin path due to config change of the bpffs directory.
Related errors
- collecting map pins to replace: %w
- opening map %s from pin: %w
- interface %s ingress: %w
- interface %s egress: %w
- updating netkit program: %w
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/c443d79e01e8a961.
Report an issue: GitHub.