coreav ffprobe and coreav ffmpeg take FFmpeg’s command lines. CoreAV implements a subset of them. A command line outside that subset either goes to the real ffprobe or ffmpeg (the fallback), or is refused (strict-safe mode).
The fallback is on by default, so a script that calls FFmpeg keeps working. If your service reads files it did not make, such as uploads, turn on strict-safe mode. In a default build, it is the only mode in which no FFmpeg code runs. A build with a decoder backend can still run an ffmpeg program to decode or encode video: what strict-safe mode covers says when.
The other commands (
probe, check, clip, split, join, remux, sanitize, extract-audio, extract-subtitles, chapters, decode-audio, hls) never run FFmpeg, in either mode.What strict-safe mode covers
Strict-safe mode turns off the command-line fallback: a command line that CoreAV does not implement is refused instead of handed to the realffprobe or ffmpeg. It does not stop coreav transcode, coreav thumbnail and the libx264 command lines of coreav ffmpeg from running an ffmpeg program as their decoder or encoder. Only builds with a decoder backend have those commands.
In none of these builds does FFmpeg open the input file or parse its container. To keep FFmpeg from encoding, use
--encoder x264 with coreav transcode, or install an x264 program (COREAV_X264, or x264 on PATH). To keep it from decoding, use a build without ffmpeg-fallback.
Turn on strict-safe mode
Set the environment variable or pass the flag:- Any value of
COREAV_STRICT_SAFEother than empty or0turns the mode on, so a mistyped value fails closed. - Under a link named
ffprobeorffmpegthat points tocoreav, every argument belongs to the tool. Only the variable works there.
What a refusal looks like
In strict-safe mode, a command line that CoreAV does not implement is refused by name, with exit status 4:-crf 90. No refusal writes or changes the output. A program that gets exit status 4 can send the job somewhere else, or reject it.
The FFmpeg fallback
Without strict-safe mode, a command line that CoreAV does not implement runs the real program instead. That program is FFmpeg’s C code, and CoreAV’s limits and checks do not apply to it. CoreAV says so in one line on standard error, at every log level,-v quiet included:
Which program runs
- If
COREAV_FALLBACKis set, it names the program. A directory names itsffmpegandffprobe(with.exeon Windows). A file names that one program. If the path does not exist, cannot run, or names the other tool, nothing runs: the refusal stands, with exit status 4 and a line that names the variable and the reason. - Otherwise CoreAV runs the first
ffmpegorffprobeonPATHthat it can run and that is notcoreavitself. - If there is none, the refusal stands, with exit status 4.
What is never handed on
Only a refusal goes to FFmpeg. These keep their own exit status and never reach FFmpeg:Log the commands that were not native
SetCOREAV_FALLBACK_LOG to a file path, and CoreAV appends one JSON line for each command line that was not native, whether FFmpeg ran it or CoreAV refused it:
INPUT, OUTPUT, VALUE), so the log holds nothing private and you can share it. Only option names and values that FFmpeg publicly lists are kept. When nothing ran, ran is null and not_run says why: strict_safe, no_program, fallback_unusable or recursion_guard. A log that cannot be written costs one line on standard error and never stops the command.
The recursion guard
The program that the fallback starts getsCOREAV_FALLBACK_ACTIVE=1 in its environment. A coreav started with that variable set never falls back. It refuses with exit status 4 instead, so a wrapper script or a renamed copy of coreav on PATH cannot cause a loop.
Decoding through FFmpeg in builds with a decoder backend
Builds with theffmpeg-fallback build feature also use an ffmpeg program to decode video for coreav thumbnail, coreav transcode and the libx264 command lines of coreav ffmpeg. This is a separate path from the command-line fallback. Strict-safe mode does not turn it off, and it is never in a default build:
- CoreAV demuxes the file itself and sends FFmpeg only the packets of one video stream, in a Matroska stream that CoreAV writes. FFmpeg’s container probing never runs on the untrusted file.
- The decoder is chosen by name from an allowlist, so a file cannot steer FFmpeg to another decoder.
- FFmpeg runs as a child of a separate worker process with resource limits. Its libraries are never linked into CoreAV.
More detail
- Fallback to FFmpeg, the design note, covers the rules above in full, including how the log is redacted.
- The FFmpeg fallback and the sandboxed worker cover the decode path.