Issue with SSH Connection in Execute Command Node – Workflow Shows as Successful Despite SSH Connection Error

Hi everyone,
I’m facing an issue with the Execute Command node in my n8n workflow. The node connects via SSH to a remote server and executes a command. However, despite encountering an SSH connection error (as shown in stderr), the workflow is marked as successful instead of failing.

(I can only share an image since this workflow is private)

I have configured the node to retry up to three times on failure, but even after three retries, the workflow still completes successfully. Here’s the relevant output from the node logs:

[
{
“exitCode”: 0,
“stderr”: “Connection closed by 11.111.111.11 port 22”,
“stdout”: “”
}
]

Questions:

  • We have some doubts regarding the retry on fail feature. Could it be that the retry on fail is altering the process in a way that results in the output showed above?

  • Did SSH successfully connect, but the server closed the session before the command could be executed successfully? In this case, the shell did not return the actual error, which may be why the workflow is not failing as expected.

Additional Information:

  • In the past, this type of error would have returned a command failed error with the following log:

Command failed: ssh [email protected] startfcconsistgrp -prep -restore Cyber Connection closed by 11.111.111.111 port 22

Information on your n8n setup

  • n8n version: 1.75.2
  • Database (default: SQLite): default
  • n8n EXECUTIONS_PROCESS setting (default: own, main): default
  • Running n8n via (Docker, npm, n8n cloud, desktop app): Docker
  • Operating system: Linux

Hey there!

Let’s break down your questions and the behavior you’re seeing:

  1. Why Isn’t “Retry On Fail” Working?

The Retry On Fail feature only triggers if the node is marked as failed (i.e., exitCode ≠ 0). In your case, since SSH returns exitCode: 0 even with stderr: "Connection closed...", n8n doesn’t recognize it as a failure, so it doesn’t retry.
This explains why your workflow “succeeds” after 3 attempts: the node isn’t actually failing—it’s retrying a command that looks successful to n8n.

Quick Fix:

  • Force exitCode ≠ 0 when connection errors occur (see Step 2 below).
  • After this fix, Retry On Fail will work as expected!
  1. Is the SSH Server Closing the Connection Early?

Yes, exactly! The SSH client connects, but the server kills the session before your remote command finishes. Here’s why this happens:

  • exitCode: 0 is returned because the SSH client doesn’t treat abrupt disconnects as failures.
  • stderr shows "Connection closed...", but n8n doesn’t auto-detect this as an error.

Common Causes:

  • SSH server timeouts due to inactivity.
  • Firewalls killing long-running connections.
  • Remote commands not returning proper error codes.

The Fix:

Step 1: Update Your SSH Command

Add error handling to force exitCode ≠ 0:

ssh -o ConnectTimeout=10 user@host “startfcconsistgrp -prep -restore Cyber || exit 1”

What This Does:

  • || exit 1 ensures any command/connection failure returns exitCode: 1.
  • -o ConnectTimeout=10 sets a 10-second connection timeout (adjust as needed).

Step 2: Use a Wrapper Script (Optional)

Create ssh-wrapper.sh for better error control:

#!/bin/bash
stderr_output=$(ssh -o ConnectTimeout=10 user@host “startfcconsistgrp -prep -restore Cyber” 2>&1)
exit_code=$?

Fail if connection closed OR exit code ≠ 0

if [[ “$stderr_output” == “Connection closed” ]] || [[ $exit_code -ne 0 ]]; then
echo “$stderr_output” >&2
exit 1
fi

echo “Command succeeded!”
exit 0

Run it in your node:

bash ssh-wrapper.sh

Step 3: Update Your Workflow

  • Enable Continue On Fail** in the SSH node.
  • Add an IF node after SSH with this condition:

{{ $node[“SSH”].json.exitCode != 0 or $node[“SSH”].json.stderr.includes(“Connection closed”) }}

  • Connect the Throw Error node to the error branch.

Workflow Example:

SSH Node (Continue On Fail :white_check_mark:)


IF Node → Error? → Throw Error :rotating_light:


Next Step :tada:

Why This Works:

  • The exitCode now reflects both connection and command failures.
  • Retry On Fail will trigger because the node is actually failing.
  • The "Connection closed..." error is treated as a failure, even if SSH says exitCode: 0.

Tips:

  1. Keep SSH Connections Alive:
    Add -o ServerAliveInterval=30 to send “keep-alive” pulses every 30 seconds:

ssh -o ConnectTimeout=10 -o ServerAliveInterval=30 user@host “your-command”

Check Your SSH Client Version:
If this worked before but now doesn’t, your container’s SSH client might have updated. Test it with:

docker exec -it n8n-container ssh -V

Let me know if this helps! If you’re still stuck, share the test results (scrub any sensitive info), and we’ll tweak the solution.

Cheers,
Dandy

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.