An OSS-Fuzz project lives in a folder under projects with three files: project.yaml for metadata, a Dockerfile that sets up the build environment, and build.sh that compiles your fuzz targets into an output folder. You test it locally with the helper script before asking for acceptance.
The three files
project.yaml holds metadata such as the homepage, language, primary contact and main repository. Supported language values listed in the new project guide are c, c++, go, rust, python, jvm, swift, javascript and lua.
Dockerfile defines the container. It usually starts from the OSS-Fuzz base builder image, or a language specific one such as the Go builder, installs build dependencies, and clones your source.
build.sh runs inside that container. It builds the project and the fuzz targets and writes the binaries to the folder named by the OUT variable.
You can generate templates with python3 infra/helper.py generate PROJECT_NAME --language=LANGUAGE.
Variables you must respect
Do not hardcode compilers or flags. Use CC, CXX, CFLAGS, CXXFLAGS, and link fuzz targets with LIB_FUZZING_ENGINE. The guide says to use CXX as the linker even for pure C projects. Honoring these lets OSS-Fuzz swap engines and sanitizers without touching your script.
Engines and sanitizers
The guide says libfuzzer, afl, honggfuzz and centipede are used by default, and that libfuzzer is required. Linking against LIB_FUZZING_ENGINE means you do not assume libFuzzer. For sanitizers it lists address, memory and undefined: address and undefined are the defaults, memory is recommended but opt-in because every dependency must be built with it.
Build rules worth knowing
- Output only extensionless binaries to OUT, since extensions are reserved for artifacts like dictionary files.
- Name binaries with only letters, digits, underscores or dashes.
- Build fuzzers statically linked, because shared libraries may not exist at runtime.
- Do not remove source files, since coverage reports need them.
- Keep the output under 10 GB uncompressed.
Test locally
The helper script gives you a loop to run before you submit:
build_imagebuilds the Docker image.build_fuzzerswith a sanitizer option builds your targets. Test each sanitizer you plan to use.check_buildfinds build problems.run_fuzzerruns a target with a corpus folder.coverageproduces a coverage report.
Who gets accepted
OSS-Fuzz is for open source projects. The acceptance page says a project must have a significant user base and or be critical to global IT infrastructure. You open a pull request that adds the project.yaml. The primary contact must belong to an established committer and be tied to a Google account. Projects that do not qualify can still use the same targets in their own CI, as our post on fuzzing pull requests explains.
What OSS-Fuzz does not do for you
It runs targets and files bugs, but someone has to write good targets. The FAQ notes that bugs are by default opened on the OSS-Fuzz tracker, not publicly, because of security access control, and that code coverage reports are public. Even if you are not accepted, keeping targets in your own repo is the recommended design.
Quick check
Do I have to use libFuzzer?
You must write a libFuzzer compatible target, but link against LIB_FUZZING_ENGINE so other engines can run it too.
Can closed source projects join OSS-Fuzz?
The FAQ says projects must be open source. It points closed source projects to ClusterFuzz.
Sources
Last reviewed: 19 October 2026.