SSH node never seems to fire "Error" output when "Continue (using error output)" is selected

Describe the problem/error/question

If I have an “SSH” node where I have selected “Continue (using error output)”, and then I intentionally cause an error by e.g. telling it to SSH to a non-existent domain, the SSH node flashes up what seems to be an error (red “X”, message like “getaddrinfo ENOTFOUND oiooijaewfoiwauefhiuh.com”), however, the SSH node still activates the “Success” output. Nothing I can do seems to activate the “Error” output. It seems like there’s a bug and the “Error” output from an SSH node can simply never get activated?

What is the error message (if any)?

Please share your workflow

Information on your n8n setup

  • n8n version: 2.13.4
  • Database (default: SQLite): MySQL
  • n8n EXECUTIONS_PROCESS setting (default: own, main): own, main
  • Running n8n via (Docker, npm, n8n cloud, desktop app): npm
  • Operating system: Debian 13

Add an IF node after SSH and check the output data for an error field or empty result. Not ideal or fancy, but it works, until the node properly propagates, it happens.

Appreciate the tip on the workaround. Conditioning on the “code” input field being empty seems to let me get at this. Is there some place I can/should submit a formal bug report, or does the team use this forum as their tracker? [Sorry, brand new to n8n, here]. :slight_smile:

This is a known quirk with how the SSH node handles low-level connection errors versus execution errors.

The “Continue (using error output)” path in n8n triggers when the node throws a workflow-level error during execution. The problem with DNS/connection failures in the SSH node is that they happen during the TCP handshake phase, before the node’s execution logic is fully entered. Depending on the n8n version and the SSH node implementation, that class of error may get absorbed by the underlying library and returned as a failed item on the success output (with error metadata on the item) rather than routing to the error connector.

A few things to try:

  1. Check the item’s $json on the success output — even when routing incorrectly, the item should contain error info like { "error": "getaddrinfo ENOTFOUND ..." }. You can branch on this with an IF node checking {{ $json.error !== undefined }}.

  2. Use a dedicated error workflow — if this is a critical path, set a workflow-level error handler (Settings > Error Workflow) to catch failures that slip through the node-level routing.

  3. Test with a different error type — try causing an auth failure (wrong password, wrong user) after a successful TCP connection. That type of error does reliably route to the error output because it happens at the execution level. If that works but DNS failures don’t, it confirms this is the connection-phase issue.

This appears to be a gap in the SSH node’s error handling specifically for pre-connection failures. Worth filing a GitHub issue if you haven’t already, as it’s genuinely unexpected behaviour.

1 Like

Good explanation @RianKellyIT of the connection-phase vs execution-phase split. On 2.13.4 this behaviour is still present in the SSH node. What finally worked reliably for me was wrapping the SSH node in a Try-Catch node at the same workflow level — the Try-Catch catches the SSH execution errors and routes them explicitly to the error stream. Alternatively, place an Error Handler node immediately after the SSH node to capture stderr directly, which bypasses the SSH node’s output limitation. I’d also file that GitHub issue you mentioned — this really should route connection errors to the error output.

1 Like

Yup that´s actually a better approach than mine, there´s a bug on the SSH that´s for sure

Yeah, connection-phase failures really should route to the error output — the current behaviour is genuinely confusing. Worth filing that GitHub issue so it gets tracked by the team.

I unfortunately don’t have time to redo the report on github, but I’m replying again here per the “n8n assistant” mail request I just received. This issue is indeed still open.