BPF portability analyzer for compiled eBPF object files.

Takes a .bpf.o and tells you: what kernel version you need, what helpers and maps you depend on, how data flows between kernel and userspace, and whether your CO-RE usage is correct.

Works on compiled ELF, not source code. Language-agnostic - C, Rust, Go, Zig all produce BPF ELF with BTF.

```

Pre-built binary (Linux amd64)

curl -L https://github.com/boratanrikulu/bpfvet/releases/latest/download/bpfvet-linux-amd64 -o bpfvet
chmod +x bpfvet
./bpfvet program.bpf.o

Or via go install

go install github.com/boratanrikulu/bpfvet/cmd/bpfvet@latest
```

Pre-built binaries for all platforms: releases.

```
$ bpfvet program.bpf.o

Minimum kernel: 5.8
License: GPL
BTF: yes, CO-RE relocations: 2 (vmlinux.h likely used)
Transport: event streaming via RingBuf

Kernel Requirements:
bpf_ringbuf_output -> 5.8+
bpf_probe_read_kernel -> 5.5+
bpf_get_current_task -> 4.8+
Kprobe program type -> 4.1+

Maps:
events RingBuf key=0B val=0B max=262144 (5.8+)

Programs:
my_probe (kprobe/do_sys_openat2, Kprobe, 29 insns)
```

Analyze multiple variants side by side. Useful for projects that compile different versions for different kernel tiers:

```
$ bpfvet *.bpf.o

==> good_core.bpf.o <==
Minimum kernel: 5.8
...

==> map_only.bpf.o <==
Minimum kernel: 4.7
...

=============================
Summary
=============================
good_core.bpf.o 5.8+
map_only.bpf.o 4.7+

Minimum kernel version (all files): 5.8
```

When a program accesses kernel structs without CO-RE relocations, bpfvet flags it:

```
$ bpfvet trace.bpf.o

Minimum kernel: 5.8
License: GPL
BTF: yes, CO-RE relocations: 0 (vmlinux.h may not be used)

WARNINGS:
ERROR trace.bpf.c:24 Direct access to kernel struct field at offset 1496
Use BPF_CORE_READ() for portability across kernel versions

Programs:
bad_probe (kprobe/do_sys_openat2, Kprobe, 11 insns)
Memory accesses: 1 total (1 KERNEL-DIRECT)
```

Note: programs built with vmlinux.h (which includes preserve_access_index on all kernel structs) get automatic CO-RE relocations even for direct field access like task->pid. This warning only fires for programs using manually defined structs without CO-RE attributes.

  • Minimum kernel version - computed from helpers, program types, and map types
  • Kernel helpers - each helper mapped to its introduction version
  • Program types - kprobe (4.1+), sock_ops (4.13+), LSM (5.7+), etc.
  • Map types - RingBuf (5.8+), LRUHash (4.10+), PerfEventArray (4.3+), etc.
  • BTF and CO-RE - BTF presence, CO-RE relocation count, vmlinux.h usage hint
  • Transport - how the program ships data to userspace (PerfEventArray, RingBuf, shared maps)
  • Memory access classification - CO-RE protected, context, map-value, kernel-direct, uncategorized
  • License - extracted from the BPF object

bpfvet program.bpf.o # text report bpfvet --json program.bpf.o # JSON (for CI) bpfvet --verbose program.bpf.o # per-program helper details bpfvet *.bpf.o # multi-file with summary

Use --json to enforce kernel version targets in CI pipelines. See docs/ci.md for GitHub Actions, GitLab CI, and Makefile examples.

bpfvet --json program.bpf.o | jq -e '.minKernel == "5.4"'

Parses BPF ELF using cilium/ebpf. Only reads the ELF - never loads into the kernel. Runs on macOS, Linux, and Windows without root.

Requires Go 1.24+.

git clone https://github.com/boratanrikulu/bpfvet.git && cd bpfvet make build ./bin/bpfvet program.bpf.o

MIT. See LICENSE.

Copyright (c) 2026 Bora Tanrikulu \<me@bora.sh>