{"record":{"id":"cf14ab95170dcb56","repo":"pentaho/pentaho-kettle","slug":"ssh-connection-failed","errorCode":null,"errorMessage":"SSH connection failed - ","messagePattern":"SSH connection failed - ","errorType":"exception","errorClass":"SshConnectionException","httpStatus":null,"severity":"critical","filePath":"engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSshConnection.java","lineNumber":135,"sourceCode":"    client = SshClient.setUpDefaultClient();\n\n    // Disable strict host key checking to avoid key exchange issues\n    client.setServerKeyVerifier( ( clientSession, remoteAddress, serverKey ) -> true );\n\n    client.start();\n  }\n\n  private ConnectFuture createConnection() throws SshConnectionException {\n    try {\n      if ( isProxyConfigured() ) {\n        return createProxyConnection();\n      } else {\n        return createDirectConnection();\n      }\n    } catch ( SshConnectionException e ) {\n      throw e; // Re-throw SshConnectionException as-is\n    } catch ( Exception e ) {\n      throw new SshConnectionException( buildConnectionErrorMessage( e ), e );\n    }\n  }\n\n  private boolean isProxyConfigured() {\n    return config.getProxyHost() != null && !config.getProxyHost().trim().isEmpty();\n  }\n\n  private ConnectFuture createDirectConnection() throws IOException {\n    log( DEBUG, \"SSH Direct Connection: \" + config.getHost() + \":\" + config.getPort()\n        + formatUserInfo() );\n    return client.connect( config.getUsername(), config.getHost(), config.getPort() );\n  }\n\n  private ConnectFuture createProxyConnection() throws SshConnectionException, IOException {\n    log( BASIC, \"SSH over HTTP Proxy: \" + config.getProxyHost() + \":\" + config.getProxyPort()\n        + \" -> \" + config.getHost() + \":\" + config.getPort() );\n    log( DEBUG, \"HTTP Proxy Details - Target User: \" + config.getUsername() + \", Auth: \" + config.getAuthType() );\n","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSshConnection.java#L117-L153","documentation":"MinaSshConnection.createConnection() catches any Exception during SSH session establishment and rethrows it as SshConnectionException with message built from buildConnectionErrorMessage(e). It is the generic connect-failure path; the specific reason (refused, auth, key, timeout) is in the cause and the enriched message.","triggerScenarios":"Calling connect() when the host is unreachable/port closed, credentials or key auth rejected, no supported key exchange/cipher negotiated, or the proxy path throws an unexpected exception type.","commonSituations":"Wrong host/port in the SSH connection metadata, SSH server firewalling the client, unsupported or passphrase-protected private key without a supplied passphrase, server disabled the auth method the client tries, or MINA SSHD version incompatibility with the server's algorithms.","solutions":["Read the full message/cause to get the concrete failure (refused vs auth vs algorithm negotiation)","Test basic reachability: ping/telnet to host:port from the same machine","Verify username/password or key file and passphrase are correct and the key format is supported (OpenSSH/PEM)","If the server only offers legacy algorithms, enable them in the SSH client or update the server; upgrade the MINA SSHD library if negotiation fails","Check proxy configuration if isProxyConfigured() is true, since the proxy path is exercised instead of the direct one"],"exampleFix":"// before\nSshConnection conn = new MinaSshConnection(config);\nconn.connect(); // opaque failure\n// after\ntry {\n  conn.connect();\n} catch (SshConnectionException e) {\n  log.error(\"SSH connect to {}:{} failed: {}\", config.getHost(), config.getPort(), e.getMessage(), e.getCause());\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"// pre-flight before connect()\nif (config.getHost() == null || config.getHost().isBlank()) throw new IllegalArgumentException(\"host required\");\nif (config.getPort() <= 0) throw new IllegalArgumentException(\"port required\");\ntry (Socket s = new Socket()) { s.connect(new InetSocketAddress(config.getHost(), config.getPort()), 5000); }\ncatch (IOException e) { throw new IllegalStateException(\"host:port unreachable before SSH attempt\", e); }","typeGuard":"boolean reachable(String host, int port) {\n  try (Socket s = new Socket()) { s.connect(new InetSocketAddress(host, port), 5000); return true; }\n  catch (IOException e) { return false; }\n}","tryCatchPattern":"try {\n  conn.connect();\n} catch (SshConnectionException e) {\n  Throwable root = e;\n  while (root.getCause() != null) root = root.getCause();\n  log.error(\"SSH connect failed (root cause: {}): {}\", root.getClass().getSimpleName(), root.getMessage());\n  throw e;\n}","preventionTips":["Pre-flight TCP reachability of host:port before the SSH handshake","Validate credentials/key paths and passphrases in config before connecting","Align cipher/KEX algorithms with the server (test with ssh -vv); upgrade the MINA SSHD library if needed","Unwrap and log the root cause chain — this error message alone hides the real reason"],"tags":["ssh","connection","network","authentication"],"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"}