Identity and machine
Distro, family, architecture, virtualisation, container; the hardware (CPU, cores, memory, GPUs, disks) and the toolchain (gcc, clang, rustc, go, python…).
Test your binary on real distro kernels.
See why it fails elsewhere.
WHY IT BREAKS ELSEWHERE
A program that works on your machine can break elsewhere: musl instead of glibc, a RHEL 4.18 kernel, no BTF, perf_event_paranoid at 3, lockdown on…
bpf() calls — never deduced from a version number, because RHEL kernels backport a lot.--json, --junit for CI and --markdown for a pull-request comment.ENVPROBE / THE PROBE UNDERNEATH
envprobe lists what can change how a userspace or kernel-facing program behaves. It works on its own, read-only, and reports missing or refused values with their reasons.
Distro, family, architecture, virtualisation, container; the hardware (CPU, cores, memory, GPUs, disks) and the toolchain (gcc, clang, rustc, go, python…).
Release, command line, config (CONFIG_BPF*, KPROBES, DEBUG_INFO_BTF, FUNCTION_TRACER and dynamic ftrace…), modules.
sysctls, LSM, SELinux, AppArmor, lockdown, Secure Boot, capabilities, seccomp, user namespaces and soft/hard RLIMIT_MEMLOCK.
Program types, map types and helpers probed with real bpf() calls; software and hardware perf_event_open, PMU; tracefs, kallsyms, BTF.
libc and its version, common libraries, FHS (merged-usr, multiarch), /bin/sh, coreutils, init, package manager, cgroups, XDG.
ok with the value, unavailable with the reason, denied when access was refused — and privileged marks what changes with the process’s rights.
JSON with a schema_version, and its schema published with the code.
envprobe schema
Compare another distro’s userspace from its extracted rootfs, in user, mount and pid namespaces, without root. The kernel stays the host’s.
scripts/probe-rootfs.sh <rootfs> <envprobe> --json
Built against musl: envprobe runs as is in any x86_64 VM or container.
FROM A TOML FILE TO A VERDICT
Describe the targets once; distroproof up boots them in parallel and tells you what differs where it fails.
IN THE TERMINAL
Not “it broke on Ubuntu 18.04” — which difference, out of all of them, is the likely reason.
distroproof upLINUX[ubuntu-18.04] failed (exit code 1) compared with ubuntu-22.04: 65 significant differences likely cause: btf.vmlinux: present, 5286152 bytes → unavailable (/sys/kernel/btf/vmlinux missing) also: kernel.CONFIG_DEBUG_INFO_BTF: y → missing from config
A failing target compared to the closest passing one. Example translated into English.
Examples adapted from the distroproof reference, with the verdict translated into English. file_caps grants capabilities to the installed binary after setup; collect brings result files back per target. Setup and command receive DP_TARGET and DP_IMAGE. The TUI adds live logs, report diffs and a console.
TARGETS / THE KERNELS IT BOOTS
Official cloud images on their own kernels. Versions below were observed in the October 2026 case study; rolling and daily images change.
| Image | Kernel observed | Note |
|---|---|---|
debian-10 · 11 · 12 · 13 | 4.19 · 5.10 · 6.1 · 6.12 | 4.19 without BTF; 13 boots in UEFI |
ubuntu-18.04 · 20.04 · 22.04 · 24.04 | 4.15 · 5.4 · 5.15 · 6.8 | 4.15 without BTF |
rocky-8 · 9 | 4.18 · 5.14 | RHEL kernels with backports; 9 boots in UEFI |
debian-sid | 7.2.11 | daily image; UEFI |
fedora-previous · fedora-latest | 6.17 · 6.19 (Fedora 43 · 44) | releases resolved online |
arch | 7.2.9 in the case study | rolling |
gentoo | 6.18 dist-kernel | OpenRC; UEFI |
alpine | 6.18 virt | musl, busybox |
nixos | 6.12 (NixOS 25.05) | Hydra’s Proxmox image; no FHS paths |
aarch64: debian-13 · ubuntu-24.04 · fedora-latest | their own arm64 kernels | emulated on an x86_64 host |
Host needs qemu-system-x86_64, qemu-img, curl, KVM (falls back to TCG without /dev/kvm) and OVMF for the UEFI-only images.
IN PRACTICE / THE EVIDENCE
Choose a target to read what happened: the problem, the finding and the result. Each story names its evidence and the scope of its validation.
OPEN SOURCE / BUILT FOR LINUX
Download the static binaries, then run your first target.
v=v0.1.0 t=x86_64-unknown-linux-musl curl -fLO https://github.com/devutils-org/distroproof/releases/download/$v/distroproof-$v-$t.tar.gz gh attestation verify distroproof-$v-$t.tar.gz --repo devutils-org/distroproof tar xzf distroproof-$v-$t.tar.gz && export PATH="$PWD/distroproof-$v-$t:$PATH" # then distroproof run --target rocky-8 -- envprobe --json > rocky8.json distroproof up # the matrix in distroproof.toml