n8n logon8n Automation Hub
Incident report

Five Unrelated n8n Workflows Failed With SSH Errors on the Same Evening — None of Them Were the Bug

Incident report · n8n workflow · September 9, 2026

A short-form video publisher, a finance-content publisher, a crypto trading bot, and a football-content publisher have nothing to do with each other. On one evening, all four failed with SSH errors within the same two-hour span, in two separate waves. The bug wasn't in any of them.

Workflow at a glance
  1. Around 18:00 CEST, a video publisher's SSH step failed with ECONNRESET, then a manual retry two minutes later failed differently, with "Connection lost before handshake"
  2. Two hours later, around 20:00 CEST the same evening, a completely separate football-content publisher and a crypto trading bot both failed within 30 seconds of each other with the identical error: Timed out while waiting for handshake
  3. A finance-content publisher failed at the same 20:00 CEST mark too, on both its scheduled run and an immediate manual retry
  4. Four different products, four different SSH credentials' worth of workflow logic, four different failing nodes — but every failure was in the SSH connection step itself, never inside the command that step was trying to run
  5. The server's sshd showed 11 of 10-100 startups at the time — over its default limit of 10 concurrent unauthenticated connections — alongside a burst of anonymous connection attempts; fail2ban was active but wasn't banning fast enough to stop the limit from being hit

Four failures that all pointed away from each other

The first failure of the evening looked like a video pipeline having a bad day: the SSH node "Copy Video to Public Host" died with ECONNRESET, and a manual retry two minutes later failed again, this time at an earlier step, "Fetch Watermarked Video," with "Connection lost before handshake." Different node, different error text, same SSH-layer failure — that pattern alone would normally point toward network flakiness specific to that one workflow's file-transfer steps.

Two hours later, a completely different picture: a football-content publisher's "SSH - Read Segment Manifest" node and a crypto-options trading bot's SSH-based iteration step both failed within 30 seconds of each other, both throwing the exact same error text — Timed out while waiting for handshake — straight from the underlying ssh2 client library. A finance-content publisher failed at the same mark too, both on its own schedule and on an immediate manual retry. None of these four workflows share a credential's usage pattern, a Sheet, a video pipeline, or even a product. The football publisher was trying to read a manifest file. The trading bot was trying to run a paper-trading iteration script. Neither has anything in common with the other except that both dial out over SSH to the same server.

The tell: every failure died before doing any work

Looking at each execution's path individually, the pattern is consistent: every single one failed at the SSH connection step itself, before the remote command it was trying to run had a chance to execute at all. Not a bad file path, not a permissions error, not a command that ran and returned a bad exit code — the TCP/SSH handshake itself never completed, or completed and then got reset mid-session. That's a strong signal to stop looking at any individual workflow's own logic and start looking at the shared thing underneath all of them: the SSH server itself, and the network path to it.

What was actually happening on the server

sshd's own status at the time showed 11 of 10-100 startups — a count of concurrent, not-yet-authenticated connections that had crossed the server's default MaxStartups threshold of 10. Alongside it, a burst of anonymous connection attempts was landing every few seconds, the unmistakable shape of an automated brute-force scan hitting the SSH port from across the internet, not a targeted attack on any credential used by these workflows specifically. fail2ban was installed and actively banning offending IPs, but not fast enough to keep the concurrent-connection count under the threshold during the burst — once MaxStartups is hit, the SSH daemon starts refusing or delaying every new connection attempt, including completely legitimate ones from n8n's own automation, indiscriminately.

That's the mechanism behind both failure shapes seen that evening: a connection that gets a slot but then has it yanked mid-negotiation looks like ECONNRESET or "Connection lost before handshake"; a connection that can't get a slot at all just sits and eventually times out client-side as "Timed out while waiting for handshake." Same root cause, two different symptoms depending on exactly when in the flood each workflow's SSH node happened to try connecting.

Why this is genuinely hard to diagnose from inside any one workflow

Debugging any single one of these executions in isolation, with no visibility into what else was happening on the server at that moment, offers no way to reach the real cause. Every clue available inside the n8n execution log — the node name, the error text, the workflow's own recent history — points toward that workflow's own SSH step being unreliable. The only thing that actually reveals the shared cause is noticing that multiple, otherwise-unrelated workflows failed at the SSH layer within the same short window, which requires looking at execution history across the whole instance rather than debugging one workflow at a time.

What actually helps

Two independent layers, not one fix: retryOnFail with a short delay on every SSH node across every workflow that depends on this server, so a transient connection-slot refusal during a flood gets absorbed instead of failing the whole run outright — this alone recovers most of these incidents without any human involved. Separately, and not something a workflow-level fix can touch: hardening the SSH server itself against exactly this class of flood, since fail2ban alone wasn't reacting fast enough to prevent MaxStartups saturation during a genuine burst. The generalizable lesson: when two or more workflows that share nothing except a common piece of infrastructure fail around the same time, check that shared infrastructure's own health before touching any workflow's logic — the failure signature will look local to each one, but the fix never is.

Multiple workflows failing at once, in ways that don't look connected?

I debug production n8n workflows for a living, including the infrastructure-level causes that only show up when you stop looking at one workflow at a time.