go-delve/delve · error

no eBPF program loaded

Error message

no eBPF program loaded

What it means

EBPFContext.AttachUprobe requires a loaded eBPF object (the compiled trace.bpf.o programs loaded into the kernel). If ctx.executable is nil — meaning InitializeEBPF never completed or the program failed to load — attaching a uprobe to trace a function is impossible and this error is returned.

Source

Thrown at pkg/proc/internal/ebpf/helpers.go:190

	}
	ctx.m.Unlock()

	if ctx.bpfRingBuf != nil {
		ctx.bpfRingBuf.Close()
	}

	for _, l := range ctx.links {
		l.Close()
	}

	if ctx.objs != nil {
		ctx.objs.Close()
	}
}

func (ctx *EBPFContext) AttachUprobe(pid int, name string, offset uint64) error {
	if ctx.executable == nil {
		return errors.New("no eBPF program loaded")
	}
	l, err := ctx.executable.Uprobe(name, ctx.objs.tracePrograms.UprobeDlvTrace, &link.UprobeOptions{PID: pid, Address: offset})
	ctx.links = append(ctx.links, l)
	return err
}

func (ctx *EBPFContext) UpdateArgMap(key uint64, goidOffset int64, args []UProbeArgMap, gAddrOffset uint64, isret bool) error {
	if ctx.bpfArgMap == nil {
		return errors.New("eBPF map not loaded")
	}

	// Store DWARF types and parameter names for later lookup during ring buffer
	// event parsing. Uses a global index: input params at 0..n-1, return params
	// at n..n+m-1. Held under ctx.m to prevent data race with pollEvents.
	ctx.m.Lock()
	if !isret {
		ctx.nInputParams[key] = len(args)
	}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Run Delve with the required privileges (sudo / CAP_BPF, CAP_PERFMON, CAP_SYS_RESOURCE)
  2. Check kernel version and that BPF syscall is enabled (CONFIG_BPF_SYSCALL, CONFIG_KPROBE_EVENTS/UPROBE_EVENTS)
  3. Verify the eBPF object for your arch was built (make build-ebpf-object) and matches the kernel
  4. Fall back to non-eBPF tracing (dlv trace without --ebpf) if the environment cannot support it
Defensive patterns

Strategy: validation

Validate before calling

// before enabling --ebpf, check privileges and kernel support:
if _, err := os.Stat("/sys/kernel/debug/tracing/uprobe_events"); err != nil {
    return errors.New("uprobe support missing; use non-eBPF tracing")
}
// and run with CAP_BPF/CAP_PERFMON (e.g. sudo setcap or run under sudo)

Try / catch

if err := ebpfCtx.AttachUprobe(pid, "main.foo", off); err != nil {
    if strings.Contains(err.Error(), "no eBPF program loaded") {
        log.Printf("eBPF init failed; falling back to standard tracepoints: %v", err)
        useRegularTrace()
    }
}

Prevention

When it happens

Trigger: Calling AttachUprobe on a non-linux build with ebpf enabled but program load failed, or after InitializeEBPF failed to load the eBPF object (missing privileges, unsupported kernel, missing compiled object) and the context was still used.

Common situations: Running 'dlv trace --ebpf' on a kernel older than required or without CAP_BPF/CAP_PERFMON/CAP_SYS_RESOURCE; kernel without eBPF (CONFIG_BPF_SYSCALL off); missing/upgraded kernel invalidating the embedded .o; running inside restricted containers/seccomp.

Related errors


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/4951381d2017a44e. Report an issue: GitHub.