n8n Disabled the Execute Command Node. Your FFmpeg Needs HTTP.

Your n8n upgrade finished, the instance came back up, and the workflow that has been burning captions into clips since spring now dies on the node that used to run ffmpeg. The error doesn't mention FFmpeg. It doesn't mention the shell either, which is why the first hour of debugging goes into the wrong container.
Quick answer: The n8n Execute Command node is disabled by default in n8n 2.0 because arbitrary shell execution is a security risk on shared instances, so FFmpeg workflows that called ffmpeg -i through it stop running the moment you upgrade. On self-hosted n8n you can put the node back through n8n's node-filtering environment variables, but that only helps if you own the instance and the image still ships an FFmpeg binary. The durable fix is to replace the Execute Command node with an HTTP Request node that posts the job to a video API such as FFmpeg Micro, which survives upgrades and works on n8n Cloud too.What n8n 2.0 changed about Execute Command
The Execute Command node was never removed from n8n's codebase. It was moved out of the default-enabled set, which is a different thing and breaks differently. n8n community thread 233388, titled "Execute Command Node has removed" and opened in December 2025, is a user watching FFmpeg workflows stop after a 2.0 upgrade and assuming the node was deleted.
The reasoning is boring and correct: a node that runs arbitrary shell commands as the n8n process user is a privilege escalation waiting to happen on any instance with more than one person on it. n8n Cloud never allowed it. Self-hosted instances did, and a huge amount of published n8n video advice quietly assumed that would stay true forever.
That's the part worth internalizing. Three separate n8n platform decisions have now broken FFmpeg workflows: Execute Command going default-off in 2.0, the official Docker image going distroless in June 2026 (thread 298633, where apk add ffmpeg stopped working), and the still-open feature request 261143 asking n8n to just bundle FFmpeg, which has been live since February 2026 without shipping. Every one of those breaks the same architecture: n8n as the machine that runs the encoder.
Disabled, missing, or present with no FFmpeg
Three different failures produce "my FFmpeg step doesn't work anymore," and they have different fixes. Work out which one you have before changing anything, because the Dockerfile edits that fix the third one do nothing for the first.
The Execute Command node being disabled looks like this: search the node panel for "Execute Command" and it isn't there. Open the saved workflow and the node renders as unknown or unrecognized rather than as a configured node, and the execution fails before any command runs. No exit code, because nothing was ever executed.
The node being present but the binary being absent looks completely different. The node runs, returns fast, and hands you exit code 127 with ffmpeg: not found on stderr. Exit code 127 is the shell's "command not found," and it's the single most useful signal in this whole mess: it proves the node is alive and your image is the problem. That's the distroless case, and the container-side fixes for it are in n8n's distroless image broke your FFmpeg Dockerfile and n8n says "ffmpeg: not found".
A third variant catches people who inherited an instance: the node is disabled by someone's explicit NODES_EXCLUDE setting from a previous hardening pass, not by the 2.0 default. Same symptom, same fix, different person to talk to.
Run this in the n8n container before you touch anything else:
docker exec -it n8n sh -c 'which ffmpeg && ffmpeg -version | head -1'
If that prints a path and a version, your binary is fine and the node is your problem. If it errors, you have a container problem, and possibly both.
The self-hosted re-enable path, and its expiry date
Self-hosted n8n exposes node filtering through environment variables, NODES_EXCLUDE and NODES_INCLUDE, and the Execute Command node identifier is n8n-nodes-base.executeCommand. Putting the node back means explicitly allowing it again in your environment config and restarting the instance. Check n8n's environment variable reference for the current list syntax on your exact version, because the filtering behavior around 2.0 is the thing that just changed under you.
Then the real question: who else uses this instance? The moment n8n is shared with a contractor, a client, a teammate who imports templates from the community gallery, or an AI Agent node that can be steered by untrusted input, you have re-armed arbitrary shell execution for all of them. A workflow that can run ffmpeg can run cat /home/node/.n8n/config and post it to a webhook. That's why n8n flipped the default, and re-enabling it puts you back on the wrong side of that decision permanently, not just today.
There's also the maintenance cost nobody prices in. Re-enabling the node only restores the shell. You still own the FFmpeg install, and that install now has to survive every future base image change, which is what the distroless break already demonstrated. You're volunteering to re-verify a multi-stage Dockerfile hack on every n8n release.
The migration: HTTP Request instead of a shell
The replacement is a straight swap. The Execute Command node becomes an HTTP Request node, the FFmpeg command becomes a JSON payload, and the video file never enters n8n's memory at all. That last part matters more than the node change: n8n's long-running complaint thread on large video files is people OOMing an entire instance by reading a 1 GB file from disk to pass it between nodes. Passing URLs instead of bytes fixes a failure class you were going to hit anyway.
Here's the before and after for a common job, burning an SRT into a video.
# Before: inside the Execute Command node, on your own box
ffmpeg -i /data/input.mp4 -vf "subtitles=/data/captions.srt" \
-c:v libx264 -crf 23 -c:a copy /data/output.mp4
# After: an HTTP Request node, POST, JSON body, no binary anywhere
curl -X POST https://api.ffmpeg-micro.com/v1/jobs \
-H "Authorization: Bearer $FFMPEG_MICRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input_url": "https://your-bucket.s3.amazonaws.com/input.mp4",
"operation": "burn_subtitles",
"subtitles_url": "https://your-bucket.s3.amazonaws.com/captions.srt",
"webhook_url": "https://your-n8n.example.com/webhook/caption-done"
}'
Check the FFmpeg Micro docs for the exact operation names and field names for your job, since the catalog covers transcoding, composition, captions, watermarks, and audio work and each takes its own parameters. The shape is always the same: submit a job, get an ID back, receive a webhook or poll for the output URL. No servers to run, no binary to install, free tier to test the swap before you migrate anything real.
The wiring in n8n, in order:
- Delete the Execute Command node and drop an HTTP Request node in its place.
- Set method POST, URL
https://api.ffmpeg-micro.com/v1/jobs, body content type JSON. - Add the API key as a header auth credential so it never sits in the node body as plain text.
- Point
input_urlat a presigned S3 or Drive URL from the previous node instead of a local path. - Add a Webhook node for the callback, and connect the rest of your workflow to that, not to the HTTP Request node.
Step 5 is the one people skip. Wiring the next node directly to the HTTP Request response means you're holding an n8n execution open while an encoder works, and n8n's HTTP timeout will kill it on anything long. The callback patterns are covered in webhooks for long-running video jobs.
Pitfalls that bite during the cutover
Most of the pain in this migration comes from assumptions the Execute Command node let you make about the filesystem. Those assumptions stop being true the second the encoder lives somewhere else.
Local paths are the first casualty. /data/input.mp4 meant something to a container that no longer does the work. Every input needs to be a URL the API can actually fetch, which means presigned links for private buckets and a real expiry window, ideally longer than your job's worst-case queue time.
Quote escaping stops being your problem, which is good, but it hides bugs you'd been carrying. Filter graphs that only worked because of a specific shell quoting accident may need to be re-expressed as parameters. Test one file end to end before you re-point production.
Error handling changes shape too. You used to branch on exit codes, and now you branch on HTTP status plus job status. A 200 on submission means the job was accepted, not that it succeeded. Handle the failed-job callback explicitly or a corrupt input will silently produce no output and your workflow will look like it worked.
When this is the wrong move
An HTTP Request node against a hosted API is the wrong call when the video never leaves a private network and compliance forbids sending it out, or when you're doing thousands of hours of transcoding a month and a dedicated managed transcoding pipeline with committed-use pricing beats per-job billing. It's also wrong if what you actually want is a template editor with a visual timeline, since a job API composes clips but doesn't give you a canvas.
If you'd rather stay inside the n8n node panel, there's a crowded field of vendor-published community nodes that wrap hosted FFmpeg services, and a comparison of the n8n FFmpeg nodes covers the trade-offs. The honest downside of any of them is the same one that just bit you: an installed node is one more thing with a version that can break on upgrade, while an HTTP Request node is core n8n and isn't going anywhere.
FAQ
Is the n8n Execute Command node removed in 2.0?
The n8n Execute Command node is not removed in 2.0, it's disabled by default. The code still ships with n8n, but the node is excluded from the enabled set unless a self-hosted operator explicitly allows it again through environment configuration.
Why did my FFmpeg workflow break after upgrading n8n?
An FFmpeg workflow that used the Execute Command node breaks after an n8n 2.0 upgrade because the node it depended on is no longer enabled, so the shell command never runs. A second, separate break hits workflows on the official Docker image, which went distroless in 2026 and no longer lets you install FFmpeg with apk add.
Can I use the Execute Command node on n8n Cloud?
The Execute Command node is not available on n8n Cloud and never has been. Running FFmpeg from n8n Cloud requires calling out over HTTP to a video processing API, because Cloud gives you no shell and no container to install binaries into.
How do I tell whether the node is disabled or FFmpeg is just missing?
Check the exit code. A disabled Execute Command node fails before executing anything and shows as an unknown node in the editor, while a present node with no binary returns exit code 127 and ffmpeg: not found on stderr.
Does replacing Execute Command with HTTP Request fix the memory problems too?
Replacing Execute Command with an HTTP Request node fixes n8n memory blowups as a side effect, because the video file stops passing through n8n as binary data. You send a URL and receive a URL, so a 2 GB source file costs the same instance memory as a 2 MB one.
Swapping one node is a twenty-minute change, and it's the last time this particular workflow breaks on an n8n release. Sign up free, grab a key, and run one caption job through the HTTP Request node before you migrate the rest.
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

FFmpeg cropdetect isn't one-shot. Detect black bars per file
ffmpeg cropdetect finds black bars on one file fine, then breaks in a batch. Sample past the intro, take the last crop line, round to even, crop per file.

16kHz Mono WAV for Whisper, Without a Local FFmpeg Binary
The FFmpeg 16kHz mono WAV command Whisper needs, plus the pipeline half: pulling audio from an MP4, size math, channel picks, and no local binary to install.

How to Use FFmpeg with React Native After FFmpegKit's Retirement
ffmpeg-kit-react-native is retired and its binaries 404. What each FFmpeg React Native option can still do, and how to offload the encode server side.
Ready to process videos at scale?
Start using FFmpeg Micro's simple API today. No infrastructure required.
Get Started Free