Reproducible build
A reproducible build gives bit-for-bit identical output whenever anyone builds the same source code with the same build environment and build instructions.
Last updated: November 11, 2026
A reproducible build gives bit-for-bit identical output whenever anyone builds the same source code with the same build environment and the same build instructions. That is the Reproducible Builds project's definition. The output here means the artifacts the build is for: executables, distribution packages, container or filesystem images. Logs do not count. "It builds again" is not the same thing; reproducible means the bytes match.
Why most builds are not reproducible
- Dependency resolution at build time. Without a lockfile, a package manager picks versions when the build runs. PyPI resolution can end differently depending on the order responses arrive, a version range moves when a new release comes out, and a mutable tag such as
latestpoints somewhere new. - The environment. Timestamps, file paths, the locale and the host's own tools end up inside the artifacts.
- Randomness. Build steps can generate IDs, order files by hash or run work in parallel in a different order each time.
So building the same commit twice in a row gives no guarantee of the same result, or of the same SBOM. A build that downloads code its lockfile does not list, a hidden dependency, makes this worse.
How teams make builds reproducible
- Pin and lock every input, including base images by digest and tools by version (see lockfile).
- Use a fixed time instead of the clock:
SOURCE_DATE_EPOCHis a standard environment variable holding a Unix timestamp that build tools use in place of the current time. - Strip or normalize build paths, sort file lists, and fix the locale.
- Build in a hermetic environment whose toolchain is itself pinned. Nix is one way to do this.
- Verify it: build the same commit twice, independently (on another machine, in another path, on another day), and compare the outputs. Where the hashes differ, diffoscope shows exactly what changed.
The Yocto Project shows why reproducibility is a property to verify rather than assume. Its documentation says the project's builds have been reproducible "down to the binary level including timestamps" since release 3.1, that only BitBake and OpenEmbedded-Core guarantee complete reproducibility, and that "the moment you add another layer, this warranty is voided." The project tests it with oe-selftest.
Reproducible builds and SBOMs
If every build were reproducible, you could rebuild an old release later and generate its SBOM. Most are not, so a rebuild, or a scan of the source today, describes a similar build rather than the one you shipped. The SBOM that shows what is in production is the one recorded from the CI build that produced the release.
Even a reproducible build does not remove the need for that record. Matching hashes prove that two builds produced the same output; they do not list what went into it. You still need the inventory, and an honest statement of its SBOM completeness. Why CI is the place for supply chain security and SBOM best practices make the longer argument.
SLSA treats reproducibility as one way to verify that a build did what it claims.
Reproducibility is something teams achieve in their build system, with tools such as Nix, Yocto or Debian's tooling. CRACI does not make builds reproducible: it records each build's SBOM as the build runs, so the record of what shipped does not depend on rebuilding it. See build-time SBOMs.