Skip to main content
v2026.11,986 entries · CC-BY 4.0

AFL++ Fuzzer: Install, Run and Read Results

AFL++ fuzzer guide: install via Docker or source, instrument a target, run afl-fuzz, read the status screen and triage crashes.

Written and maintained by CASRAI Editorial Board

Published

On this page

AFL++ is an open-source fuzzer: a program that repeatedly feeds mutated inputs to another program, watches which code paths each input reaches, and keeps the inputs that reach new ones, so that crashes and hangs in the tested software surface without anyone writing individual test cases. Its project README calls it a state-of-the-art fuzzer and describes it as a fork of Google’s AFL. Researchers use it to find memory-safety and robustness faults in parsers, libraries and command-line tools, and to produce reproducible evidence for security papers.

What AFL++ is used for in research

AFL++ (not to be confused with the Australian Football League) is a coverage-guided fuzzer. You compile the program you want to test with an AFL++ compiler wrapper so it reports which code it executed, give afl-fuzz a small set of valid example inputs (seeds), and let it mutate them for hours or days. Inputs that cause a crash or a timeout are saved to disk so they can be replayed and reported.

In research this is most often part of software-security work: vulnerability discovery, evaluation of a new fuzzing technique against a baseline, or hardening of research software that parses untrusted files. The broader field context is in What Is Cybersecurity? A Research Field and an Institutional Duty, and one security conference where applied work of this kind appears is described in the ACSAC conference guide. The project asks users who publish results to cite Fioraldi, Maier, Eissfeldt and Heuse, “AFL++: Combining incremental steps of fuzzing research”, 14th USENIX Workshop on Offensive Technologies (WOOT 20), August 2020.

Only fuzz software you own or are authorised to test, and run it on a machine you can afford to have misbehave: a fuzzer deliberately drives the target into faulty states.

Install or access AFL++ (official sources)

There are three official routes, all documented by the AFL++ project: a Docker image, a source build, and macOS via Homebrew.

Docker

The README gives the image name aflplusplus/aflplusplus, built for x86_64 and arm64. The :dev tag tracks development.

docker pull aflplusplus/aflplusplus
docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus

Build from source on Debian or Ubuntu

The install page lists these dependencies, plus LLVM and clang (a distribution version or -14; the page recommends LLVM 13 or newer) and the matching GCC plugin development package.

sudo apt-get install -y build-essential python3-dev automake cmake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools cargo libgtk-3-dev
git clone https://github.com/AFLplusplus/AFLplusplus
cd AFLplusplus
make distrib
sudo make install

make all and make source-only are documented alternatives to make distrib, and PERFORMANCE=1 is an optional build setting.

macOS

The install page uses Homebrew (brew install wget git make cmake llvm gdb coreutils) and tells users to use the Homebrew clang rather than the one from Xcode. On macOS, afl-clang-lto, afl-gcc-fast and QEMU mode do not work; FRIDA mode with -O does. The page gives no Windows build instructions.

Licence

The repository is under AGPL-3.0-or-later by default, with some files under Apache-2.0 as marked in their SPDX headers. If you redistribute a modified AFL++ or embed it in a tool, read the licence text first; for ordinary internal use in a research project the practical effect is that you may run it freely, but changes you distribute carry the licence with them.

Step-by-step: fuzz a program from build to crash replay

The sequence below follows the project’s “fuzzing in depth” documentation. Replace target and the paths with your own program.

1. Choose an instrumentation mode

The documentation’s order of preference depends on your compiler: with clang 11 or newer use afl-clang-lto; otherwise with clang 3.8 or newer use afl-clang-fast; otherwise with a GCC 5 or newer plugin use afl-gcc-fast. The compiler-agnostic wrapper is afl-cc / afl-c++.

2. Build the target with the AFL++ compiler

For autoconf projects:

CC=afl-clang-fast CXX=afl-clang-fast++ ./configure --disable-shared
make clean all

For CMake and Meson:

cmake -DCMAKE_C_COMPILER=afl-cc -DCMAKE_CXX_COMPILER=afl-c++ ..
CC=afl-cc CXX=afl-c++ meson

With afl-clang-lto, also set AR=llvm-ar and RANLIB=llvm-ranlib. To catch memory errors that would otherwise not crash, set AFL_USE_ASAN=1 before compiling (MSAN, UBSAN, CFISAN, TSAN and LSAN have matching variables). Optional extras documented for harder targets are AFL_LLVM_CMPLOG=1, which builds a CmpLog binary used through -c, and AFL_LLVM_LAF_ALL=1.

3. Collect and minimise seed inputs

Put a few small, valid inputs for the program in a directory. To remove redundant seeds, run:

afl-cmin -i INPUTS -o INPUTS_UNIQUE -- bin/target -someopt @@

afl-tmin can then shrink each remaining seed. The @@ placeholder tells AFL++ to pass the input as a file name; leave it out if the program reads standard input.

4. Prepare the machine

Before the first run, execute sudo afl-system-config, or set AFL_SKIP_CPUFREQ=1 if you cannot change CPU settings.

5. Start the fuzzer

afl-fuzz -i input -o output -- bin/target -someopt @@

-m sets the memory limit in MB, -t the timeout, and -x adds a dictionary. Ctrl-C stops the run. To resume, point -i at a dash (afl-fuzz -i - -o output ...) or set AFL_AUTORESUME=1.

6. Add more cores

Run one main instance and any number of secondary instances against the same output directory, each with a unique name: -M main-$HOSTNAME (with AFL_FINAL_SYNC=1) for the main one and -S variant1, -S variant2 and so on for the others. The documentation suggests staying within roughly 32 to 64 cores per machine, and describes multi-machine setups that synchronise the main directory with rsync.

7. Monitor, triage and replay

afl-whatsup -s output/
afl-plot output/default /srv/www/htdocs/plot
afl-showmap -C -i output -o /dev/null -- ./target -params @@
casr-afl -i /path/to/afl/out/dir -o /path/to/casr/out/dir

afl-whatsup summarises all instances, afl-plot draws graphs from plot_data, afl-showmap -C counts coverage over a corpus, and casr-afl groups crashes into reports. afl-tmin and afl-analyze help reduce and understand a crashing input. For a target that reads standard input, a crash is replayed with cat output_dir/crashes/id:000000,* | /path/to/tested/program.

Output and how to read it

The status screen

The live screen is divided into blocks. Process timing shows how long the run has gone. Overall results show cycles done, total paths and unique crashes and hangs. Cycle progress, map coverage and stage progress show where the fuzzer is in the queue and how much of the coverage map has been touched; the execution speed in the stage progress block matters, because the documentation notes that fewer than 100 executions per second suggests a very long job. The findings-in-depth and fuzzing-strategy blocks show what has produced new paths. Path geometry reports depth, pending inputs and stability, and low stability points to non-deterministic behaviour in the target. The CPU-load indicator is green when there is spare CPU and red when the machine is oversubscribed.

The output directory

  • queue/ holds one test case per distinct execution path, plus the starting files.
  • crashes/ holds crashing inputs, grouped by the signal that killed the target.
  • hangs/ holds inputs that exceeded the timeout, which is the larger of 1 second and the -t value.
  • fuzzer_stats holds counters such as cycles_done, execs_per_sec, saved_crashes and stability.
  • plot_data holds the time series that afl-plot graphs.

The documentation warns that the number of corpus files is a poor indicator of coverage; use afl-showmap -C instead.

What to record when you report a fuzzing result

This is editorial guidance for research reporting, not a requirement of the AFL++ project. A reader who wants to rerun or judge your result needs the AFL++ version or commit, the compiler and instrumentation mode, the sanitizer settings, the seed corpus and how it was minimised, the number of instances and cores, total run time, cycles_done, stability, and how crashes were deduplicated and confirmed. Counting raw files in crashes/ overstates findings, because many inputs can trigger the same underlying fault; triage them first. Where your code or data come from a reproducible setup, the practices described in reproducible research practices apply, and if you release your harness the notes on code review of research software are a useful companion.

Troubleshooting

The “fuzzing in depth” page documents these specific failures and fixes.

Symptom Documented cause and fix
Cannot connect to the fork server The memory limit -m is too small for the target; raise it.
A build aborts because of the AFL++ compiler during configure Set AFL_NOOPT=1 while running configure, then unset it before building.
Undefined symbol __afl_area_ptr Add __afl_*; under global: in the linker script.
Several Docker instances run slowly They share one core; use --cpuset-cpus or set AFL_NO_AFFINITY.
The fuzzer rejects seed inputs Fix or replace the seeds, or set AFL_IGNORE_SEED_PROBLEMS=1 to continue.
Unexpected “crashes” with sanitizers With MSAN an exit code of 86 and with LSAN an exit code of 23 are counted as crashes.

Open-source alternatives

AFL++ is not the only coverage-guided fuzzer. The table compares how two others are described by their own documentation. The data table below the article adds build commands, licences and supported systems for all three, so you can pick by how your target is built.

Tool How its documentation describes it Typical target
AFL++ A state-of-the-art fuzzer, forked from Google’s AFL; runs a target program with afl-fuzz from the command line Programs and libraries built with an AFL++ compiler wrapper, or run in QEMU or FRIDA mode
libFuzzer “An in-process, coverage-guided, evolutionary fuzzing engine”, linked into the program under test; enabled with -fsanitize=fuzzer C and C++ libraries with a fuzz target function (LLVMFuzzerTestOneInput) that must not call exit() on any input
honggfuzz “A security-oriented, feedback-driven, evolutionary fuzzer”; multi-process and multi-threaded Programs compiled with hfuzz-clang, with an optional persistent mode

One maintenance point from libFuzzer’s documentation is worth knowing before you choose it: its original authors have moved development to another engine, Centipede, and the page says libFuzzer remains supported for important bug fixes but major new features are not expected. The AFL++ documentation also mentions compatibility with libFuzzer harnesses (built with -fsanitize=fuzzer), so check that page before rewriting a harness when you switch.

Frequently asked questions

What is AFL++ used for?

AFL++ finds crashes and hangs in software by mutating example inputs and keeping those that reach new code. In research it is used for vulnerability discovery, for evaluating new fuzzing methods and for hardening programs that parse untrusted input.

Is AFL++ the same as AFL?

No. AFL++ is a fork of Google’s original AFL, as its README states, and is a separate project with its own compilers, options and documentation.

How do I cite AFL++?

The README gives Fioraldi, Maier, Eissfeldt and Heuse, “AFL++: Combining incremental steps of fuzzing research”, 14th USENIX Workshop on Offensive Technologies (WOOT 20), August 2020.

Is AFL++ free to use?

The source is licensed under AGPL-3.0-or-later by default, with some files under Apache-2.0, as marked in the SPDX headers of each file.

Does AFL++ run on Windows or macOS?

The project’s install page gives Homebrew instructions for macOS, noting that some modes do not work there, and gives no Windows build instructions. Docker images for x86_64 and arm64 are available.

How long should I run it?

The documentation gives no fixed duration. It points to indicators instead: cycles done, new paths still being found, execution speed, and stability on the status screen.

Sources

  • AFL++ project README, https://github.com/AFLplusplus/AFLplusplus, read 14 November 2026.
  • AFL++ documentation, “Fuzzing in depth”, https://aflplus.plus/docs/fuzzing_in_depth/, read 14 November 2026.
  • AFL++ documentation, “afl-fuzz approach” (status screen and output directory), https://aflplus.plus/docs/afl-fuzz_approach/, read 14 November 2026.
  • AFL++ documentation, “Installing AFL++”, https://aflplus.plus/docs/install/, read 14 November 2026.
  • LLVM documentation, “libFuzzer”, https://llvm.org/docs/LibFuzzer.html, read 14 November 2026.
  • honggfuzz README, https://github.com/google/honggfuzz, read 14 November 2026.
  • Related reading on this site: open-source software.

Data: Coverage-guided fuzzers compared: build command, run command, licence and supported systems

Side-by-side compilation of AFL++, libFuzzer and honggfuzz from each project's own README or documentation: how a target is built, how a run is started, the licence stated, and operating systems named. Compiled 2026-11-14.

Period covered: 2026.

Coverage-guided fuzzers compared: build command, run command, licence and supported systems
FuzzerBuild or enable instrumentationExample run commandLicence stated by projectSystems named in sources
AFL++CC=afl-clang-fast CXX=afl-clang-fast++ ./configure --disable-sharedafl-fuzz -i input -o output -- bin/target -someopt @@AGPL-3.0-or-later by default; some files Apache-2.0Linux build from source; macOS via Homebrew (some modes unavailable); Docker x86_64 and arm64
libFuzzerclang -g -O1 -fsanitize=fuzzer,address mytarget.c./my_fuzzer CORPUS_DIRPart of the LLVM project (licence not stated on the documentation page)Included in Clang releases from 6.0
honggfuzz./hfuzz_cc/hfuzz-clang -o my_target my_target.c./honggfuzz -i input_dir/ -- ./my_target ___FILE___Apache License 2.0Linux, macOS, Android, NetBSD, FreeBSD, Windows (Cygwin)

Sources

Compiled by CASRAI from the sources above. Free to reuse under CC BY 4.0 with attribution.

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about AFL++ Fuzzer: Install, Run and Read Results

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →