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

  1. Regenerate eBPF objects and Go skeletons (make ebpf with clang) so the 'events' map exists and matches the skeleton
  2. Verify the object file at dirPath is current and defines the 'events' perf map (bpftool map dump / llvm-objdump)
  3. Check load errors before this check — the bpf loader usually logs the underlying failure that left Events nil
  4. 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

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


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)