A pipeline that was working, until the last five minutes of it
The execution path leading up to the failure looked completely healthy: 27 nodes total, every one of the first 23 reporting success, including three separate long-running SSH calls that each took well over a minute without incident. The final node before the failure, "SSH - Render Short (letterbox)," itself reported success at 605 seconds — over ten minutes for that one step alone. The very next node, "Check Short Render Exit Code," is the one that actually surfaced the failure, because it's a dedicated Code node whose entire job is reading the previous SSH call's exit code and throwing if it's non-zero. Without that explicit check, the SSH node's own "success" status would have hidden a failed render completely, since n8n's SSH node considers a command successful as long as the SSH session itself completed cleanly — the remote command's own exit status is just data in the output, not something n8n checks for you.
Reading the actual error instead of the label
The thrown error text was ffmpeg short (letterbox) render failed (exit code 124), followed by roughly twenty lines of ffmpeg's own stderr tail: per-frame prediction-mode statistics, reference-frame usage percentages, an average audio quantizer value — the exact kind of output ffmpeg prints continuously while a long encode is healthily in progress, not what it prints when it hits a real error. The very last line before the process ended was Exiting normally, received signal 15. Signal 15 is SIGTERM. ffmpeg didn't crash; something sent it a termination signal mid-encode, and ffmpeg shut down as gracefully as a mid-encode process can.
Exit code 124 is the confirmation: by long-standing shell convention (and specifically the behavior of the GNU timeout utility), a wrapped command that gets killed for running too long exits with 124, not with whatever exit code the underlying program would have used for its own errors. Nothing about ffmpeg's own error vocabulary produces 124 on its own.
Where the actual timeout lives
The command dispatched by the "SSH - Render Short (letterbox)" node was a single long ffmpeg invocation with no explicit timeout wrapper written into the command string itself — meaning the 124 wasn't coming from the command as authored. The more likely source is the SSH connection's own execution-time ceiling: n8n's SSH node (and the underlying SSH2 library it's built on) has no unlimited-by-default command runtime, and long-running remote commands issued this way are vulnerable to being cut off by whatever session or channel timeout sits between the n8n process and the remote shell, independent of anything ffmpeg itself is doing. The three earlier SSH steps in the same workflow (227s, 16s, 172s) all stayed comfortably under whatever that ceiling is; the final step's 605 seconds did not.
Why this is worse than a normal ffmpeg error
A real ffmpeg error — a missing filter, a bad codec parameter, a corrupt input — fails fast and says so in plain language near the top of its output. A timeout-killed ffmpeg process fails slow, after doing real, correct, expensive work, and its last visible output looks exactly like a healthy render in progress. Anyone glancing at the stderr tail without already suspecting a timeout would reasonably conclude the render itself is broken and go hunting for a codec or filter bug that doesn't exist.
The fix
Two changes: raise whatever the SSH node's effective command-execution ceiling is for this specific long-running render step (or move genuinely multi-minute renders off a single blocking SSH call entirely, toward the same async task-id-plus-polling pattern already used elsewhere in this pipeline's own image-generation step), and separately wrap the ffmpeg command itself in an explicit timeout <N>m ffmpeg ... with a deliberately generous ceiling — so that if a real hang ever does happen, the exit code and the wrapping layer are both under this workflow's own control instead of an invisible, undocumented SSH-session default. The generalizable check: an exit code of 124 from any SSH-executed command means something set a time limit and hit it — the fix is never in the command's own logic, it's in finding and adjusting whichever layer imposed that limit.
n8n Automation Hub