cilium/cilium · error
inserting host endpoint policy program: %w
Error message
inserting host endpoint policy program: %w
What it means
attachCiliumHost returns this when updating the host endpoint's policy program into the cilium_call_policy map fails: hostObj.PolicyMap.Update(uint32(ep.GetID()), hostObj.PolicyProg, ebpf.UpdateAny). This map-based tail-call dispatch is how the host endpoint's policy program is reached; a failed update means the program handle could not be inserted (map missing/renamed wrongly, key collision with different type, map full, or fd invalid).
Source
Thrown at pkg/datapath/loader/host.go:126
var hostObj hostObjects
commit, cleanup, err := collLoader.LoadAndAssign(ctx, logger, &hostObj, spec, &bpf.CollectionOptions{
MapRegistry: reg,
CollectionOptions: ebpf.CollectionOptions{
Maps: ebpf.MapOptions{PinPath: bpf.TCGlobalsPath()},
},
Constants: ciliumHostConfiguration(ep, lnc),
MapRenames: ciliumHostMapRenames(ep, lnc),
ConfigDumpPath: filepath.Join(bpfStateDeviceDir(ep.InterfaceName()), hostEndpointConfig),
}, lnc, attachmentContextHost(ep, host), bpffsDevicePluginPinsTcDir(bpf.CiliumPath(), host))
if err != nil {
return err
}
defer cleanup()
defer hostObj.Close()
// Insert host endpoint policy program.
if err := hostObj.PolicyMap.Update(uint32(ep.GetID()), hostObj.PolicyProg, ebpf.UpdateAny); err != nil {
return fmt.Errorf("inserting host endpoint policy program: %w", err)
}
// Attach cil_to_host to cilium_host ingress.
if err := attachSKBProgram(logger, host, hostObj.ToHost, symbolToHostEp,
bpffsDeviceLinksDir(bpf.CiliumPath(), host), netlink.HANDLE_MIN_INGRESS, option.Config.EnableTCX); err != nil {
return fmt.Errorf("interface %s ingress: %w", ep.InterfaceName(), err)
}
// Attach cil_from_host to cilium_host egress.
if err := attachSKBProgram(logger, host, hostObj.FromHost, symbolFromHostEp,
bpffsDeviceLinksDir(bpf.CiliumPath(), host), netlink.HANDLE_MIN_EGRESS, option.Config.EnableTCX); err != nil {
return fmt.Errorf("interface %s egress: %w", ep.InterfaceName(), err)
}
if err := commit(); err != nil {
return fmt.Errorf("committing bpf pins: %w", err)
}
return nilView on GitHub (pinned to ac7b90affa)
Solutions
- Inspect the wrapped ebpf error; if it's EINVAL/ENOENT for the map, remove stale pinned maps under /sys/fs/bpf and restart the agent.
- Verify ciliumHostMapRenames produces names matching the compiled bpf_host map names (LocalMapName(cilium_calls/cilium_policy, epID)).
- Confirm PolicyProg actually loaded (LoadAndAssign returned nil) and the program type is compatible as a tail-call target.
- Ensure ep.GetID() fits the map key type and that the endpoint ID is stable across reloads.
- Check kernel >= minimum supported version and program size within verifier complexity limits.
Example fix
// before: stale pinned policy map causes Update to fail silently-looping on reload
// after: unpin and recreate maps when update fails with ENOENT
if err := hostObj.PolicyMap.Update(uint32(ep.GetID()), hostObj.PolicyProg, ebpf.UpdateAny); err != nil {
if errors.Is(err, os.ErrNotExist) {
os.RemoveAll(bpf.TCGlobalsPath()) // clear stale pins, agent restart recreates
}
return fmt.Errorf("inserting host endpoint policy program: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
// Validate pinned map state before reload
func policyMapPinned(epID uint16) error {
name := bpf.LocalMapName(policymap.MapName, epID)
path := filepath.Join(bpf.TCGlobalsPath(), name)
if _, err := os.Stat(path); os.IsNotExist(err) {
return fmt.Errorf("pinned map %s missing at %s; clear stale pins and restart", name, path)
}
return nil
} Type guard
func isMapUpdateError(err error) bool {
var eebpf *ebpf.LoadError // or check wrapped errors from ebpf map ops
_ = eebpf
return errors.Is(err, unix.EINVAL) || errors.Is(err, unix.ENOENT) ||
errors.Is(err, unix.ENOSPC)
} Try / catch
if err := reload(); err != nil {
if strings.Contains(err.Error(), "inserting host endpoint policy program") {
if errors.Is(err, unix.ENOENT) {
// stale pin: recreate maps
cleanupStalePins(bpf.TCGlobalsPath())
retryWithBackoff(reload)
return
}
log.Error("policy program insert failed", "detail", errors.Unwrap(err))
}
} Prevention
- Clear pinned maps when upgrading between Cilium versions with map layout changes.
- Keep map renames consistent with compiled bpf_host map names.
- Ensure bpffs pin path exists and is writable before starting the agent.
- Avoid reusing endpoint IDs across restarts without map cleanup.
When it happens
Trigger: After LoadAndAssign succeeds, the PolicyMap.Update call fails: cilium_policy map renamed to include the endpoint ID doesn't match the compiled spec, the map was not pinned/persisted (PinPath missing), ep.GetID() overflows uint16-derived key or collides, or the program fd is invalid because PolicyProg did not load (verifier error swallowed earlier).
Common situations: Upgrades where cilium_policy map layout changed and stale pinned maps are reused; custom map renames registered in ciliumHostRenames conflicting with defaults; running with map pinning enabled but bpffs state directory deleted mid-run; endpoint ID churn producing mismatched map names.
Related errors
- inserting endpoint policy program: %w
- inserting endpoint egress policy program: %w
- failed to write auth information to BPF map: %w
- program %s is not a tail call
- program %s has no function metadata
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/075061867febaa09.
Report an issue: GitHub.