OpenNHP/opennhp · error
'events' map not found
Error message
'events' map not found
What it means
EbpfEngineLoad returns "'events' map not found" when the loaded eBPF object's perf-event map named 'events' (objs.Events from the generated bpf skeleton) is nil after ebpf.LoadPinnedObjects/CollectionSpec load. Without this map the engine cannot receive deny events from the kernel XDP program, so startup is aborted.
Solutions
- Regenerate eBPF objects and Go skeletons (make ebpf with clang) so the 'events' map exists and matches the skeleton
- Verify the object file at dirPath is current and defines the 'events' perf map (bpftool map dump / llvm-objdump)
- Check load errors before this check — the bpf loader usually logs the underlying failure that left Events nil
- Ensure the running kernel supports the map/program types used by the object
Example fix
// before
eventsMap := objs.Events
if eventsMap == nil {
return fmt.Errorf("'events' map not found")
}
// after
if err := objs.Load(); err != nil { // or check spec.HasMap("events")
return fmt.Errorf("load eBPF objects: %w", err)
}
eventsMap := objs.Events
if eventsMap == nil {
return fmt.Errorf("'events' map missing from object (regenerate with make ebpf)")
} Defensive patterns
Strategy: validation
Validate before calling
// before load
spec, err := ebpf.LoadCollectionSpec(objPath)
if err != nil { return err }
if _, ok := spec.Maps["events"]; !ok {
return fmt.Errorf("object %s lacks 'events' map; rebuild with make ebpf", objPath)
} Try / catch
eventsMap := objs.Events
if eventsMap == nil {
return fmt.Errorf("'events' map nil; underlying load err: %w", loadErr)
} Prevention
- Always regenerate skeletons when eBPF C sources change
- Pin object file versions alongside binary builds
- Check bpf loader errors before dereferencing skeleton fields
When it happens
Trigger: The pinned/compiled eBPF object at dirPath does not define the 'events' perf map (stale or wrong .o file), or skeleton loading partially failed leaving objs.Events nil (section name mismatch between C source and Go skeleton).
Common situations: eBPF C sources were edited to rename the events map but the Go skeleton (bpf headers) was not regenerated; deploying an old object file from a different build; make ebpf skipped so an incompatible object is present.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- eBPF functionality is only supported on Linux, current…
- failed to parse default route
- value is out of range for uint16
- unsupported protocol
- unsupported map type
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/f54aab214def1dc2.
Report an issue: GitHub.
Appendix: source
Thrown at endpoints/ac/ebpf/ebpfegine.go:175
log.Error("failed to attach XDP program to interface: %s", ifaceName)
return err
}
//load tc eBPF tc_egress.o to net interface which default route exit
tcLink, err = link.AttachTCX(link.TCXOptions{
Program: tcObjs.TcEgressProg,
Interface: iface.Index,
Attach: ebpf.AttachTCXEgress,
})
if err != nil {
log.Error("failed to attach TC egress program to interface: %s", ifaceName)
return err
}
// Accessing the Perf Buffer Map named "events" defined in eBPF.
eventsMap := objs.Events
if eventsMap == nil {
log.Error("failed to load 'events' map from eBPF object (nil)")
return fmt.Errorf("'events' map not found")
}
ExeDirPath := dirPath
//Set up the DENY logger
DenyLogger = log.NewLoggerDefine(
"",
logLevel,
filepath.Join(ExeDirPath, "logs"),
"nhp_deny",
)
DenyLogger.SetFlags(stdlog.Lmsgprefix)
// Set up the ACCEPT logger
AcLogger = log.NewLoggerDefine(
"",
logLevel,
filepath.Join(ExeDirPath, "logs"),
"nhp_accept",
)View on GitHub (pinned to 6e04ca5ff0)