Why n8n says "No usable ffmpeg was found" and what to do about it

You upgraded an n8n community node this week, ran a workflow that touches video, and it failed in about two seconds with No usable ffmpeg was found. The node's README probably told you it needs no FFmpeg installation. It does, and so does every other one.
Quick answer: "No usable ffmpeg was found" means the n8n server running your workflow has no FFmpeg binary the node can execute, and it is not a broken install: n8n's community-package installer stripsoptionalDependenciesand runsnpm install --ignore-scripts=true, so no community node can ship FFmpeg with itself. On self-hosted n8n you fix it by baking FFmpeg into your Docker image or pointingFFMPEG_PATHat a binary you installed yourself. On n8n Cloud neither of those is possible, so send the job to a hosted FFmpeg API such as FFmpeg Micro through the HTTP Request node and the workflow stops needing a binary at all.
Where the error string comes from
Conventional wisdom says this is a missing-dependency problem and the answer is to install FFmpeg. Most of page one tells you exactly that, and on a laptop it works. But the cause isn't that you forgot a step. It's that the step was never available to the node in the first place.
FFmpeg itself never prints No usable ffmpeg was found, and neither does n8n core. The string comes from the node's own binary-resolution code: it looks for an FFmpeg executable, finds nothing it can run, and gives up before any encoding starts. That's why it fails in seconds rather than timing out mid-transcode. The error is a lookup failure, not a processing failure.
Why a community node can't bring its own FFmpeg
A fix merged on October 2, 2026 in the n8n-nodes-claudecode node documents the mechanism in n8n's own source. Before installing a community package, community-packages.service.js deletes devDependencies, peerDependencies and optionalDependencies from that package's package.json, then runs npm install --ignore-scripts=true. Those two behaviors, together, kill both patterns that Node packages use to ship an FFmpeg binary.
The first pattern is @ffmpeg-installer/ffmpeg, which is only a meta package. The actual binaries live in per-platform packages like @ffmpeg-installer/linux-x64 and @ffmpeg-installer/linux-arm64, declared as optional dependencies, which is precisely the field n8n deletes. That node declared them in versions 2.7.0 and 2.8.0, so no install made through n8n ever received a binary, and video attachments failed with Video attachment "video": No usable ffmpeg was found.
The second pattern is ffmpeg-static, a regular dependency that fetches its prebuilt binary from GitHub Releases in an install-time install.js script. Being a regular dependency doesn't save it, because --ignore-scripts=true means the download never runs. So when a community node advertises "Zero Installation: Uses static binaries, no external FFmpeg/FFprobe installation required" and credits ffmpeg-static in the same README, that promise cannot survive n8n's installer. The maintainer's conclusion in that PR is the sentence worth keeping: a top-level package has no way to ship a platform binary through n8n's installer. The node now requires FFmpeg on the server and resolves it in order, an explicit FFmpeg Path setting, then the FFMPEG_PATH environment variable, then ffmpeg on the PATH.
This also answers why the same node version works for someone else. They aren't running a better install. They're running on a server that already had FFmpeg on it.
The three real options
Your fix depends entirely on whether you control the filesystem the n8n process runs on. On n8n Cloud you don't, and the community forum states it plainly: n8n Cloud allows no custom binaries and no shell access, so FFmpeg cannot be installed there at all. Here is how the three choices compare before the details.
| Option | Works on n8n Cloud | What you maintain | Survives an n8n upgrade |
|---|---|---|---|
| FFmpeg in a custom Docker image | No | A Dockerfile, per n8n tag | Needs re-verification each release |
| `FFMPEG_PATH` to a host binary | No | The binary, codecs, fonts | Only if you keep the host |
| HTTP Request to a hosted API | Yes | Nothing | Yes, no binary involved |
Bake FFmpeg into a self-hosted Docker image
Installing FFmpeg into the image is the honest self-hosted answer, and it is also the one that breaks again. The official docker.n8n.io/n8nio/n8n image no longer ships a package manager, so every apk add --no-cache ffmpeg tutorial you'll find now fails outright. Copy the binary in instead:
FROM docker.n8n.io/n8nio/n8n:2.39.8
USER root
COPY --from=mwader/static-ffmpeg:7.1 /ffmpeg /usr/local/bin/ffmpeg
COPY --from=mwader/static-ffmpeg:7.1 /ffprobe /usr/local/bin/ffprobe
USER node
Two routes were verified on September 20 and 21, 2026 against n8n 2.39.8: copying /sbin/apk and /usr/lib/libapk.so* out of a matching Alpine tag gives you FFmpeg 8.1.2 for about 150 MB, and copying mwader/static-ffmpeg gives you FFmpeg 9.0.1 for about 340 MB while logging Fontconfig error: Cannot load default config file on any run that draws text. That repo ships a verify.sh so you can re-check per n8n tag, which tells you everything about how durable the recipe is.
Point FFMPEG_PATH at a binary you installed
Setting FFMPEG_PATH tells a node where an existing binary lives. It does not create one, and that distinction is where most of the wasted hours go. Give it the full path to the executable, /usr/local/bin/ffmpeg, not the directory that contains it, and confirm the process can actually run it with docker exec -it n8n /usr/local/bin/ffmpeg -version. This route only exists if you own the filesystem, which rules out Cloud and most managed one-click deployments.
Send the job over HTTP so no node needs a binary
The third option removes the dependency instead of satisfying it. FFmpeg runs on someone else's machine, your workflow sends JSON, and the HTTP Request node that ships with n8n does the talking. The command you would have run locally:
ffmpeg -i input.mp4 output.webm
The same job as one call, which works identically from n8n Cloud and from a self-hosted container with no FFmpeg in it:
curl -X POST https://api.ffmpeg-micro.com/v1/transcodes \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"inputs": [{"url": "https://storage.example.com/input.mp4"}],
"outputFormat": "webm"
}'
You get back a job id and "status": "pending", poll GET /v1/transcodes/{id} until it reads completed, then call /v1/transcodes/{id}/download for a signed URL. That's three HTTP Request nodes and a Wait node, and FFmpeg Micro's FFmpeg API handles transcoding, thumbnails, audio extraction, watermarks and HLS the same way. Status checks and downloads are free, jobs are billed per second of input video with no rounding to the minute, and failed jobs are never billed. The free tier is 200 tokens at sign-up, roughly 33 minutes of video, with no card. Paid plans start at $19.99 a month for 2,500 tokens. If you'd rather keep a community node and only compare the approaches, we walked through the node landscape in how to use FFmpeg in n8n without touching your Docker image.
Pitfalls that produce the same symptom
Installing FFmpeg correctly and still getting nothing is common enough to check these before you rebuild again.
- Fonts are a separate install. The open feature request asking n8n to bundle FFmpeg, filed February 5, 2026 and still unanswered by staff as of its September 26 replies, warns that
fontconfigplus font packages likettf-dejavuare required ordrawtextand subtitle burn-in silently produce nothing. - The Code node may not run where you think. In external task-runner mode, scripts execute in an `n8nio/runners` sidecar that contains no FFmpeg, and the runners image version must match the n8n image. FFmpeg in your main container is invisible to it.
- Execute Command is off by default since n8n 2.0, so shelling out to FFmpeg fails even on a server that has it. We covered that break in n8n disabled the Execute Command node.
- n8n 3.0, scheduled for October 2026, flips
N8N_UNVERIFIED_PACKAGES_ENABLEDfrom true to false, so unverified community FFmpeg nodes can be disabled on upgrade with no error at all. The same release cuts the task runner timeout from 5 minutes to 1 minute, which is shorter than most real transcodes. - An Alpine tag mismatch breaks the
apkcopy trick. TheALPINE_TAGyou copy from has to match what/etc/os-releasereports inside the n8n image.
FAQ
Can I install FFmpeg on n8n Cloud at all?
No. n8n Cloud gives you no shell access and no custom binaries, so FFmpeg cannot be installed there under any node, and a community node that claims to bundle it will still fail with No usable ffmpeg was found. Calling a hosted FFmpeg API over the HTTP Request node is the only route that works on Cloud.
Does upgrading the community node fix the error?
Upgrading the node usually changes the error into a clearer requirement rather than fixing it. The October 2026 fix in n8n-nodes-claudecode removed the bundled FFmpeg entirely and documented that the binary must already exist on the server, because n8n's installer strips the dependency field that carried it.
What exactly do I set FFMPEG_PATH to?
FFMPEG_PATH takes the absolute path of the FFmpeg executable, for example /usr/local/bin/ffmpeg, not the directory holding it and not a docker exec command. A node that follows the common resolution order checks its own FFmpeg Path setting first, then FFMPEG_PATH, then whatever ffmpeg resolves to on the PATH.
Will my custom Dockerfile keep working after the next n8n release?
A custom Dockerfile keeps working until n8n changes its base image, which has already happened once: the official image dropped its package manager and invalidated every apk add ffmpeg guide written before mid-2026. Treat the Dockerfile as something you re-verify per n8n tag, not as a one-time fix.
Why do my captions and text overlays come out blank after FFmpeg is installed?
Blank text output almost always means fontconfig and font packages are missing from the container, not that FFmpeg is broken. The drawtext and subtitles filters need a usable font config, and without one they fail quietly and hand back a video with nothing drawn on it.
If you'd rather not own a binary, a font cache and a Dockerfile per n8n release, the FFmpeg Micro quickstart runs the whole flow for you: it creates a temporary API key, then walks presigned upload, transcode, poll and download with the real request and response at each step. Copy those four calls into HTTP Request nodes and the error string stops being yours to fix.
About Javid Jamae
Founder & CEO at FFmpeg Micro
Javid is a software engineer, author, and entrepreneur with over 25 years of professional software development experience across enterprise, startup, and consulting environments. He founded FFmpeg Micro to make video processing accessible to developers through a simple, automation-first REST API.
You might also like

Replace audio in video by API: the mux is the easy part
Replace audio in video API or FFmpeg CLI: measure drift with ffprobe, pad or trim instead of atempo, and re-burn captions against the new TTS timings.

Frame counts lie. FFmpeg progress percentage is in out_time_us
Parse FFmpeg's -progress output for a real ffmpeg progress percentage: out_time_us against an ffprobe duration, speed= for ETA, and where parsing breaks.

How to use FFmpeg in n8n without touching your Docker image
Most FFmpeg n8n Docker recipes break on n8n 2.x. Compare three working paths: the runners image plus fonts, a static-ffmpeg copy, and an HTTP call on Cloud.
Ready to process videos at scale?
Start using FFmpeg Micro's simple API today. No infrastructure required.
Get Started Free