Safeguard
Developer Tools•

How do you rerun a libFuzzer crash file as a regression check?

Pass the crash file to the fuzz binary instead of a corpus directory. libFuzzer reruns it once, so a fixed bug stays fixed. Steps and CI notes inside.

Safeguard Security Team
4 min read

To rerun a libFuzzer crash as a regression check, pass the crash file path to the fuzz binary instead of a corpus directory. libFuzzer then executes just those inputs without fuzzing. Keep the file in the repository and run it in CI, so the bug cannot quietly return.

What happens when you pass files

The LLVM libFuzzer documentation says that when you pass files instead of directories, libFuzzer reruns those inputs without fuzzing. That is exactly what a regression check needs: one input, one execution, a pass or a crash.

Crash inputs are typically named crash- followed by a SHA1 of the content. The -artifact_prefix option sets where those files are written, and -exact_artifact_path overrides the prefix and drops the checksum from the filename. If you want stable names in a repo, give each file a name that carries the bug ticket, not the hash.

Steps

  1. Reproduce. Run the fuzz binary with the crash file and confirm it fails the same way.
  2. Minimize. The -minimize_crash flag shrinks a crash input. The docs say to combine it with -runs=N or -max_total_time=N to limit attempts. A smaller input is easier to read in a code review.
  3. Fix the bug.
  4. Rerun the same file. It should now exit cleanly.
  5. Commit the file into a regression directory such as tests/fuzz-regressions/, with a name that points to the ticket.
  6. Add a CI step that runs the fuzz binary over that directory and fails the build on any crash.

A sketch of the command, shown as code because the exact binary name is yours:

./my_fuzzer tests/fuzz-regressions/

The same form works for a single file path. Because no fuzzing happens, the step finishes in seconds and fits a pull request check.

Keep regressions separate from the working corpus

Your working corpus grows as the fuzzer finds new coverage. The regression directory is a fixed set of past failures. Mixing them hides the purpose of each.

The docs describe -merge=1 for corpus minimization: inputs from the second and later directories that trigger new coverage are copied into the first, and the example uses a new empty directory as the first argument. Use that to shrink the working corpus. Do not run it over the regression directory, because a regression input that adds no new coverage would be dropped, and you want to keep it anyway.

What to review in a pull request

CheckWhy
The crash file is in the changeProves the fix was tested against the real trigger
The file is smallEasier to read, faster to run
The CI step covers the directoryA file nobody runs is not a test
The commit message names the ticketFuture readers know why it exists

Treat any crash file that came from a customer or from untrusted traffic carefully. It may contain data you should not store. Strip or replace sensitive content before committing, and confirm the bug still reproduces afterwards.

Try it yourself

Click through it at your own pace, or open it full screen. Look at how a failing check blocks a merge, then picture your crash replay step in that spot.

Safeguard can enforce this kind of rule as a gate on pull requests, alongside dependency and SBOM scanning. The free scan at gold.safeguard.sh/scan is a way to see what that looks like on your own repository.

Quick check

Does rerunning a crash file take long?

No. libFuzzer runs the given inputs once without fuzzing, so it usually finishes in seconds.

Should the file be minimized first?

Preferably. Use -minimize_crash with a run or time limit, then confirm the smaller file still fails before the fix.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.