Node SSH ERROR: Timed out

Describe the issue/error/question

The SSH node sometimes, when executed, gives system errors that it could not connect. Sometimes this is fine for our scenario and I would like to receive the error text and handle the exception without interrupting the whole process. For example, write data about this to the database or to the log. But with such an error, it further transfers the data to the previous node. I have also tried using the “Continue On Fail” and “Continue On Fail” switches, but it didn’t work.
How can I refer to the node’s response if it has a conditional error but we are expecting it?

What is the error message (if any)?

ERROR: Timed out while waiting for handshake

Please share the workflow

{
  "name": "Mikrotik Backup Binary Process",
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "command": "=/system backup save{{ $env.MK_BACKUP_ENCRYPT_PASSWORD ? \" dont-encrypt=no encryption=aes-sha256\" : \" dont-encrypt=yes\"}} name={{$node[\"Start\"].json[\"filenameonmikrotik\"]}}{{ $env.MK_BACKUP_ENCRYPT_PASSWORD ? \" password=\" +  $env.MK_BACKUP_ENCRYPT_PASSWORD : \"\"}}",
        "cwd": "={{}}"
      },
      "name": "SSH",
      "type": "n8n-nodes-base.ssh",
      "typeVersion": 1,
      "position": [
        460,
        300
      ],
      "notesInFlow": true,
      "alwaysOutputData": true,
      "credentials": {
        "sshPassword": {
          "id": "2",
          "name": "SSH Password account"
        }
      },
      "continueOnFail": true,
      "notes": "Create binary backup"
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "SSH",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SSH": {
      "main": [
        []
      ]
    }
  },
  "active": false,
  "settings": {
    "saveExecutionProgress": true,
    "saveManualExecutions": true
  },
  "id": 4
}

Share the output returned by the last node

ERROR: Timed out while waiting for handshake

Details

Stack

Error: Timed out while waiting for handshake
    at Timeout._onTimeout (/usr/local/lib/node_modules/n8n/node_modules/ssh2/lib/client.js:1014:23)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)

Information on your n8n setup

  • n8n version: 0.150.0
  • Database you’re using (default: SQLite): SQLite
  • Running n8n with the execution process [own(default), main]: own
  • Running n8n via [Docker, npm, n8n.cloud, desktop app]: Docker

Hi @AntonAndreevichMoroz, could you share your workflow JSON in a preformatted block? Either by using this button or by manually putting three backticks ``` before and after the snippet?

image

For your specific issue, you could set up an error workflow to handle this error as described here:

You can then read the error data from the Error Trigger node in your error workflow:

I cannot use Error Workflow for 2 reasons

  1. It does not receive data from the main workflow and from other nodes that it needs to handle the error. For example from the node Mysql.
  2. This stops the main workflow. It’s bad if, say, we have several elements going through SplitInBatches.
{
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        380,
        300
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "=SELECT * FROM devices WHERE active LIKE '1'"
      },
      "name": "MySQL",
      "type": "n8n-nodes-base.mySql",
      "typeVersion": 1,
      "position": [
        580,
        300
      ],
      "notesInFlow": true,
      "credentials": {
        "mySql": {
          "id": "1",
          "name": "MySQL account"
        }
      },
      "notes": "Get devices list"
    },
    {
      "parameters": {
        "batchSize": 1,
        "options": {}
      },
      "name": "SplitInBatches",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 1,
      "position": [
        780,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [],
          "string": [
            {
              "value1": "={{ $env.MK_BACKUP_BINARY ? $env.MK_BACKUP_BINARY : \"true\" }}",
              "value2": "true"
            }
          ]
        },
        "combineOperation": "any"
      },
      "name": "IF",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        1000,
        120
      ]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "filenamebin",
              "value": "={{$node[\"SplitInBatches\"].json[\"id\"]}}_{{$node[\"SplitInBatches\"].json[\"name\"]}}_{{new Date().toLocaleDateString()}}_{{new Date().getHours()}}.{{new Date().getMinutes()}}.{{new Date().getSeconds()}}.backup"
            },
            {
              "name": "filenameonmikrotik",
              "value": "={{$node[\"SplitInBatches\"].json[\"id\"]}}_{{$node[\"SplitInBatches\"].json[\"name\"]}}.backup"
            },
            {
              "name": "folderforbin",
              "value": "/home/node/backup/bin/"
            }
          ]
        },
        "options": {}
      },
      "name": "Set",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        1240,
        40
      ]
    },
    {
      "parameters": {
        "command": "=/system backup save{{ $env.MK_BACKUP_ENCRYPT_PASSWORD ? \" dont-encrypt=no encryption=aes-sha256\" : \" dont-encrypt=yes\"}} name={{$node[\"Set\"].json[\"filenameonmikrotik\"]}}{{ $env.MK_BACKUP_ENCRYPT_PASSWORD ? \" password=\" +  $env.MK_BACKUP_ENCRYPT_PASSWORD : \"\"}}",
        "cwd": "={{}}"
      },
      "name": "SSH",
      "type": "n8n-nodes-base.ssh",
      "typeVersion": 1,
      "position": [
        1440,
        40
      ],
      "notesInFlow": true,
      "alwaysOutputData": true,
      "credentials": {
        "sshPassword": {
          "id": "2",
          "name": "SSH Password account"
        }
      },
      "disabled": true,
      "continueOnFail": true,
      "notes": "Create binary backup"
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "MySQL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MySQL": {
      "main": [
        [
          {
            "node": "SplitInBatches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SplitInBatches": {
      "main": [
        [
          {
            "node": "IF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF": {
      "main": [
        [
          {
            "node": "Set",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set": {
      "main": [
        [
          {
            "node": "SSH",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

I’m sorry to hear this isn’t working for you.

Unfortunately, when enabling the Continue On Fail setting, the error you are seeing does not appear to be available in subsequent nodes (this seems like a bug to me and I’ve reported it internally).

The setting will, however, still cause the workflow to continue. So you could enable this setting:
image

And then check in a subsequent if node, if the result string you are getting from your SSH node matches what you are expecting. While you will not be able to use the full error details you will still have access to other items in your workflow.

I guess I don’t understand how to do it. Because the SSH host does not add any new data on error and the “Continue On Fail” option is enabled. In fact, he does not give any data, but simply continues to carry out the workflow further. Therefore, it is impossible to check and refer to the error. I would expect to see exitCode and a line from stderr the same way it does on normal execution when exitCode and stdout are given.

If you could tell me what can be compared from the SSH node in this case, then I would be grateful for the hint.

Yes, it’s unfortunately not possible to refer to the error data. Instead you would need to check whether the execution was successful.

For example when stdout contains anything, my workflow would take the success route:

When running into the error you have described, the workflow would continue on the error path instead:

Example Workflow
{
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "command": "date"
      },
      "name": "SSH",
      "type": "n8n-nodes-base.ssh",
      "typeVersion": 1,
      "position": [
        450,
        300
      ],
      "credentials": {
        "sshPassword": {
          "id": "18",
          "name": "SSH Password account"
        }
      },
      "continueOnFail": true
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{$json[\"stdout\"]}}",
              "operation": "regex",
              "value2": "/.+/"
            }
          ]
        }
      },
      "name": "IF",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        650,
        300
      ]
    },
    {
      "parameters": {},
      "name": "Success",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        850,
        200
      ]
    },
    {
      "parameters": {},
      "name": "Error",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        850,
        400
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "SSH",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SSH": {
      "main": [
        [
          {
            "node": "IF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF": {
      "main": [
        [
          {
            "node": "Success",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

This example uses a regular expression in the IF node to check if stdout contains at least one character. You might need to adjust the check slightly depending on the possible success results in your case.

1 Like