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_indexon all kernel structs) get automatic CO-RE relocations even for direct field access liketask->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>