Skip to main content
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 real ffprobe 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_SAFE other than empty or 0 turns the mode on, so a mistyped value fails closed.
  • Under a link named ffprobe or ffmpeg that points to coreav, 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:
A refusal can come after the input is opened, for example for a source with chapters, an output file that already exists, or a value such as -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:
Standard output is the program’s, byte for byte, and so is the exit status. On Unix CoreAV replaces itself with the program, so its process id and signals are FFmpeg’s too.

Which program runs

  1. If COREAV_FALLBACK is set, it names the program. A directory names its ffmpeg and ffprobe (with .exe on 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.
  2. Otherwise CoreAV runs the first ffmpeg or ffprobe on PATH that it can run and that is not coreav itself.
  3. 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

Set COREAV_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:
File names, URLs and option values become placeholders (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 gets COREAV_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 the ffmpeg-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