cilium/cilium · error
get next program: %w
Error message
get next program: %w
What it means
The BPF metrics collector's Usage() enumerates all loaded BPF programs by walking ebpf.ProgramGetNextID() starting from ID 0. If fetching the next program ID fails with anything other than os.ErrNotExist (the normal end-of-iteration signal), the walk aborts with this wrapped error. It means the program ID enumeration itself failed, not any specific program.
Source
Thrown at pkg/metrics/bpf.go:72
progPrefixes []string
programsVisited map[ebpf.ProgramID]struct{}
mapsVisited map[ebpf.MapID]struct{}
}
// Usage returns the memory usage of all BPF programs matching the filter
// specified in the constructor, as well as the memory usage of all maps
// associated with those programs.
func (v *bpfVisitor) Usage() (_ *bpfUsage, err error) {
var id ebpf.ProgramID
for {
id, err = ebpf.ProgramGetNextID(id)
if errors.Is(err, os.ErrNotExist) {
break
}
if err != nil {
return nil, fmt.Errorf("get next program: %w", err)
}
if err := v.visitProgram(id, v.progPrefixes); err != nil {
return nil, fmt.Errorf("check program %d: %w", id, err)
}
}
return &v.bpfUsage, nil
}
// visitProgram opens the given program by id and collects its memory usage and
// that of all maps it uses.
//
// If prefixes are specified, the program is only checked if its name starts
// with one of the prefixes. This is useful to omit programs that are not
// relevant for the caller.
func (v *bpfVisitor) visitProgram(id ebpf.ProgramID, prefixes []string) error {
if _, ok := v.programsVisited[id]; ok {View on GitHub (pinned to ac7b90affa)
Solutions
- Grant CAP_BPF (and CAP_SYS_ADMIN on older kernels) to the process collecting metrics
- Check kernel version >= 4.13 for program ID iteration support
- Inspect the wrapped root error to identify syscall denial (EPERM/ENOSYS) and adjust LSM/seccomp policy accordingly
- Verify the bpf filesystem is mounted for ID enumeration
Defensive patterns
Strategy: validation
Validate before calling
// Verify BPF iteration is permitted before collecting metrics
if _, err := ebpf.ProgramGetNextID(0); err != nil && !errors.Is(err, os.ErrNotExist) {
if errors.Is(err, os.ErrPermission) {
return errors.New("need CAP_BPF to enumerate BPF programs")
}
return fmt.Errorf("program ID enumeration unavailable: %w", err)
} Try / catch
// Go: classify the enumeration failure
usage, err := v.Usage()
if err != nil {
var permErr syscall.Errno
if errors.As(err, &permErr) && permErr == syscall.EPERM {
// degrade metrics instead of hard-failing the scrape
}
return err
} Prevention
- Grant CAP_BPF to metrics collectors that walk BPF objects
- Check kernel >= 4.13 before enabling BPF ID-based metrics
- Review seccomp/LSM profiles for denials of BPF iteration commands
- Log the unwrapped root error, not just the wrapper, for diagnosis
When it happens
Trigger: Calling Usage() (metrics collection) on a system where ProgramGetNextID returns an unexpected error — e.g. missing privileges to iterate BPF objects, kernel without BPF program iteration support (pre-4.13 kernels), or bpf() syscall denials by LSM/seccomp policy.
Common situations: Running the metrics endpoint in an unprivileged container lacking CAP_BPF; hardened environments where seccomp blocks BPF commands; old kernels predating BPF ID enumeration.
Related errors
- failed to query for multicast group: %w
- failed to lookup subscriber %s: %w
- check program %d: %w
- open program by id: %w
- get program info: %w
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/db7438b990a1bf85.
Report an issue: GitHub.