Watch at EaseStories. Answers. Perspective.

Technology · PRACTICAL GUIDE

FFmpeg concat still fails after -safe 0? Identify the layer before adding flags

Preserve the original list, resolved input and argument boundaries. A controlled local WAV test separates filename policy from parsing, URL bases and protocol permissions.

Original editorial illustration: list parsing, URL resolution and protocol permission are separate layers.
Original editorial illustration: list parsing, URL resolution and protocol permission are separate layers. Watch at Ease

The concat demuxer’s -safe 0 permits filenames its default policy rejects. It does not repair a malformed list, create a missing file or authorize every nested protocol. Follow the first specific error, rather than repeatedly changing the last line of a failed command.

Make one incident record before changing anything

Keep original media unchanged. Save the actual list file, exact executable/build, working directory and complete stderr. Record whether -i receives a regular file, stdin or a wrapper-generated URL. Do not diagnose a filename from a retyped or AI-reformatted transcript.

For a trusted local list, inspect with ffprobe -v error -f concat -safe 0 -i list.ffconcat -show_streams -of json, replacing the path. It does not produce a joined media file. Keep exit status and stderr even when stdout contains JSON; empty JSON alone is not success.

Use a regular-file baseline to separate policy and parsing

Put one known local input in a small duplicate list. A space-containing entry can be written as file 'clip one.wav'. The single quotes belong in the list; double quotes around the list’s command-line path serve a different parser. Apostrophes need the documented concat escaping rules.

Our synthetic 0.1-second WAV tests on Ubuntu ffprobe 6.1.1-3ubuntu5 rejected that entry with safe 1 and opened it with safe 0. Double-quoting the entry still failed. Moving the list into a subdirectory changed its resolved relative path; a correct absolute path restored opening. These are controlled Linux observations, not a Windows or Unicode diagnosis.

Treat stdin and protocol errors as a new branch

If the regular list opens but stdin fails, compare the exact resolved URL and named protocol. In our build, -i - used fd. A file,pipe allowlist rejected fd; permitting the observed transport still left a relative or bare absolute entry resolved under fd. An explicit file: absolute URL then opened.

Do not copy that allowlist as a universal fix. Inspect your build and original error, authorize only the protocols your trusted input actually needs, or retain the simpler regular-list route. -safe 0 cannot fix a protocol rejection. If no streams are detected, making a later map optional can hide the symptom without opening the intended input.

Keep wrapper arguments and verify the right outcome

In Python, pass the executable and each argument as separate subprocess.run list elements with shell=False. Capture stdout, stderr and returncode; keep list bytes separately before text decoding or newline conversion. Shell quoting inside an argument list does not fix the separate concat-file grammar. Windows argument conversion and batch-file behavior have additional documented rules.

Repeat the same probe after one change and confirm the intended input and streams. Then validate stream compatibility, required tracks and the complete output separately. Timestamp warnings after opening belong to a different investigation; neither a successful probe nor silencing errors proves a correct join.

Original editorial illustration: our synthetic WAV control separates regular lists from stdin.
Original editorial illustration: our synthetic WAV control separates regular lists from stdin. Watch at Ease