Build the same commit twice, then compare the two outputs with diffoscope. It unpacks archives recursively, turns binary formats into readable text, and shows exactly what differs. You can then trace each difference to a timestamp, a path, a file ordering problem or a tool version, instead of guessing from a hash mismatch.
Why a hash mismatch is not enough
A SHA-256 mismatch tells you two files differ. It does not tell you where, or why. For a jar, an APK or a container layer, the difference may be buried three archives deep in a single embedded date.
Diffoscope is built for that case. Its own description says it tries to get to the bottom of what makes files or directories different, by recursively unpacking archives of many kinds and transforming binary formats into forms a person can read. It can compare two tarballs, two ISO images or two PDFs just as easily. The list of supported formats on the project site is long and includes Android APK files, ZIP archives, ELF binaries, Java class files, Debian packages and NuGet packages.
Steps to run a comparison
- Check out the commit twice, into two different directories. Different paths make path leaks visible.
- Build each copy with your normal release command and keep the outputs.
- Compare hashes with sha256sum. If they match, you are done.
- If they differ, run diffoscope on the two artifacts.
- Read the report from the top. Fix the first cause, rebuild, and compare again.
The project site shows a Docker invocation that mounts the current directory read only, so you do not need to install anything. It also lists installation through pip, apt, dnf, Homebrew and others, and an online try page.
docker run --rm -t -w $(pwd) -v $(pwd):$(pwd):ro \
registry.salsa.debian.org/reproducible-builds/diffoscope build-a.jar build-b.jar
At the time of this review the site lists release 334, dated 16 October 2026.
Reading the report: common causes and fixes
Most differences fall into a few families. The reproducible-builds.org documentation covers each of them.
| What you see in the diff | Likely cause | Usual fix |
|---|---|---|
| Different modification times on archive members | Build time recorded in the archive | Set one timestamp, such as SOURCE_DATE_EPOCH |
| Same files, different order | Directory listing order differs between runs | Sort inputs when creating the archive |
| Different owner or group names | The build user was recorded | Record numeric owner 0 |
| A directory such as /home/ci/work in strings | Build path in debug info or macros | Remap the path prefix at compile time |
| Different version string | Build date or abbreviated hash embedded | Derive version from source only |
If the table shows a cause you recognise, the fix is usually one setting. If the difference is inside a compiled binary, check the compiler and linker flags first.
Know what a clean result proves
When both builds match, you have shown the output depends on your declared inputs, on that day, on those machines. That is useful, but it is not proof the source is safe. A reproducible build of vulnerable or malicious source is still reproducible.
Maven's guide makes a related point: a local rebuild does not prove a third party can reproduce the build, because environment leaks such as username or current directory may still exist. Treat the first clean comparison as the start, then try a second machine.
Try it yourself
Safeguard is not needed to run diffoscope. Once your builds are stable, an SBOM from dependency scanning shows what went into the artifact. Safeguard's SBOM and dependency scanning is generally available, and the free scan at gold.safeguard.sh/scan can inventory a repository. Click through the demo to see what an inventory looks like.
Click through it at your own pace, or open it full screen.
Quick check
Does diffoscope fix the differences?
No. It only reports them. You fix the cause in the build, then compare again.
Should I compare logs too?
Usually not. The reproducible builds definition says artifacts are the primary outputs and do not usually include build logs.
Sources
- diffoscope project site
- Reproducible Builds: Archive metadata
- Reproducible Builds: Build path
- Reproducible Builds: Definitions
- Maven: Guide to configuring for reproducible builds
Last reviewed: 19 October 2026.