{"record":{"id":"db7438b990a1bf85","repo":"cilium/cilium","slug":"get-next-program-w","errorCode":null,"errorMessage":"get next program: %w","messagePattern":"get next program: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/metrics/bpf.go","lineNumber":72,"sourceCode":"\n\tprogPrefixes []string\n\n\tprogramsVisited map[ebpf.ProgramID]struct{}\n\tmapsVisited     map[ebpf.MapID]struct{}\n}\n\n// Usage returns the memory usage of all BPF programs matching the filter\n// specified in the constructor, as well as the memory usage of all maps\n// associated with those programs.\nfunc (v *bpfVisitor) Usage() (_ *bpfUsage, err error) {\n\tvar id ebpf.ProgramID\n\tfor {\n\t\tid, err = ebpf.ProgramGetNextID(id)\n\t\tif errors.Is(err, os.ErrNotExist) {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"get next program: %w\", err)\n\t\t}\n\n\t\tif err := v.visitProgram(id, v.progPrefixes); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"check program %d: %w\", id, err)\n\t\t}\n\t}\n\n\treturn &v.bpfUsage, nil\n}\n\n// visitProgram opens the given program by id and collects its memory usage and\n// that of all maps it uses.\n//\n// If prefixes are specified, the program is only checked if its name starts\n// with one of the prefixes. This is useful to omit programs that are not\n// relevant for the caller.\nfunc (v *bpfVisitor) visitProgram(id ebpf.ProgramID, prefixes []string) error {\n\tif _, ok := v.programsVisited[id]; ok {","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/metrics/bpf.go#L54-L90","documentation":"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.","triggerScenarios":"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.","commonSituations":"Running the metrics endpoint in an unprivileged container lacking CAP_BPF; hardened environments where seccomp blocks BPF commands; old kernels predating BPF ID enumeration.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify BPF iteration is permitted before collecting metrics\nif _, err := ebpf.ProgramGetNextID(0); err != nil && !errors.Is(err, os.ErrNotExist) {\n    if errors.Is(err, os.ErrPermission) {\n        return errors.New(\"need CAP_BPF to enumerate BPF programs\")\n    }\n    return fmt.Errorf(\"program ID enumeration unavailable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"// Go: classify the enumeration failure\nusage, err := v.Usage()\nif err != nil {\n    var permErr syscall.Errno\n    if errors.As(err, &permErr) && permErr == syscall.EPERM {\n        // degrade metrics instead of hard-failing the scrape\n    }\n    return err\n}","preventionTips":["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"],"tags":["ebpf","metrics","permissions","kernel"],"backgroundTag":"bpf-program-id-iteration-failed","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}