{"record":{"id":"03ff38e0067cca12","repo":"pentaho/pentaho-kettle","slug":"ssh-connection-failed-during-await","errorCode":null,"errorMessage":"SSH connection failed during await","messagePattern":"SSH connection failed during await","errorType":"exception","errorClass":"SshConnectionException","httpStatus":null,"severity":"critical","filePath":"engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSshConnection.java","lineNumber":257,"sourceCode":"    return errorMsg.toString();\n  }\n\n  private void waitForConnection( ConnectFuture cf ) throws SshConnectionException {\n    // PDI-20898: In MINA SSHD 2.x await(0L) behaves like a non-blocking poll and can return\n    // immediately without waiting for connection completion. Use no-argument await() for\n    // non-positive timeouts; it waits\n    // until the connection is established with no deadline imposed.\n    long connectTimeout = config.getConnectTimeoutMillis();\n    boolean connected;\n\n    try {\n      if ( connectTimeout > 0 ) {\n        connected = cf.await( connectTimeout );\n      } else {\n        connected = cf.await();\n      }\n    } catch ( IOException e ) {\n      throw new SshConnectionException( \"SSH connection failed during await\", e );\n    }\n\n    if ( !connected ) {\n      if ( connectTimeout > 0 ) {\n        throw new SshTimeoutException( \"SSH connection timed out after \" + connectTimeout + \"ms\" );\n      }\n      throw new SshTimeoutException( \"SSH connection failed while waiting with no configured timeout\" );\n    }\n\n    if ( !cf.isConnected() ) {\n      Throwable cause = cf.getException();\n      throw new SshConnectionException( \"SSH connection failed\", cause );\n    }\n  }\n\n  private ClientSession establishSession( ConnectFuture cf ) throws SshConnectionException {\n    ClientSession s = cf.getSession();\n","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSshConnection.java#L239-L275","documentation":"MinaSshConnection.waitForConnection() wraps IOException from ConnectFuture.await() into SshConnectionException(\"SSH connection failed during await\"). The future wait itself failed at the I/O level, distinct from a timeout (which throws SshTimeoutException) or a clean auth rejection.","triggerScenarios":"Calling connect() when the underlying socket/I/O errors out while waiting on the connect future: connection reset during handshake, interrupted/failed I/O in the MINA session, or local resource exhaustion preventing the await from completing.","commonSituations":"Firewalls that accept the TCP handshake then drop the packet flow (breaking the SSH handshake), VPN drops mid-connect, very short-lived network instability, or server-side MaxStartups throttling that resets the connection during key exchange.","solutions":["Retry the connection with exponential backoff; transient handshake drops are common","Check firewall/NAT/VPN stability between client and server (handshake-accept-then-drop behavior)","Check server sshd logs for MaxStartups/PerSource limits resetting early connections","Verify the SSH server completes key exchange (test with ssh -vvv from the same host)","Distinguish from timeout: if you see SshTimeoutException instead, raise connectTimeout"],"exampleFix":"// before\nconn.connect();\n// after\nint attempts = 0;\nwhile (true) {\n  try { conn.connect(); break; }\n  catch (SshConnectionException e) {\n    if (++attempts > 3) throw e;\n    Thread.sleep(1000L * attempts);\n  }\n}","handlingStrategy":"retry","validationCode":"// pre-flight reachability and a sane timeout before connect\ntry (Socket s = new Socket()) { s.connect(new InetSocketAddress(config.getHost(), config.getPort()), 5000); }\ncatch (IOException e) { throw new IllegalStateException(\"network unstable: \" + e.getMessage(), e); }\n// ensure connectTimeout > 0 so failures surface as SshTimeoutException, not indefinite await","typeGuard":"boolean sshReachable(String host, int port) {\n  try (Socket s = new Socket()) { s.connect(new InetSocketAddress(host, port), 3000); return true; }\n  catch (IOException e) { return false; }\n}","tryCatchPattern":"try {\n  conn.connect();\n} catch (SshConnectionException e) {\n  if (\"SSH connection failed during await\".equals(e.getMessage())) {\n    // transient handshake drop — retry once, then surface\n  } else { throw e; }\n} catch (SshTimeoutException t) {\n  throw new IOException(\"SSH timed out; raise connectTimeout or fix network\", t);\n}","preventionTips":["Always set a positive connectTimeout so hangs become clean SshTimeoutExceptions","Retry transient await failures with short backoff; they are usually network blips","Stabilize VPN/NAT/firewall paths that accept TCP then drop mid-handshake","Check server-side MaxStartups/PerSource throttling when drops cluster at connect time"],"tags":["ssh","connection","network","handshake"],"backgroundTag":"connection-refused","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}