pentaho/pentaho-kettle · critical · SshConnectionException

SSH connection failed during await

Error message

SSH connection failed during await

What it means

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.

Solutions

  1. Retry the connection with exponential backoff; transient handshake drops are common
  2. Check firewall/NAT/VPN stability between client and server (handshake-accept-then-drop behavior)
  3. Check server sshd logs for MaxStartups/PerSource limits resetting early connections
  4. Verify the SSH server completes key exchange (test with ssh -vvv from the same host)
  5. Distinguish from timeout: if you see SshTimeoutException instead, raise connectTimeout

Example fix

// before
conn.connect();
// after
int attempts = 0;
while (true) {
  try { conn.connect(); break; }
  catch (SshConnectionException e) {
    if (++attempts > 3) throw e;
    Thread.sleep(1000L * attempts);
  }
}
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight reachability and a sane timeout before connect
try (Socket s = new Socket()) { s.connect(new InetSocketAddress(config.getHost(), config.getPort()), 5000); }
catch (IOException e) { throw new IllegalStateException("network unstable: " + e.getMessage(), e); }
// ensure connectTimeout > 0 so failures surface as SshTimeoutException, not indefinite await

Type guard

boolean sshReachable(String host, int port) {
  try (Socket s = new Socket()) { s.connect(new InetSocketAddress(host, port), 3000); return true; }
  catch (IOException e) { return false; }
}

Try / catch

try {
  conn.connect();
} catch (SshConnectionException e) {
  if ("SSH connection failed during await".equals(e.getMessage())) {
    // transient handshake drop — retry once, then surface
  } else { throw e; }
} catch (SshTimeoutException t) {
  throw new IOException("SSH timed out; raise connectTimeout or fix network", t);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/03ff38e0067cca12. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSshConnection.java:257

    return errorMsg.toString();
  }

  private void waitForConnection( ConnectFuture cf ) throws SshConnectionException {
    // PDI-20898: In MINA SSHD 2.x await(0L) behaves like a non-blocking poll and can return
    // immediately without waiting for connection completion. Use no-argument await() for
    // non-positive timeouts; it waits
    // until the connection is established with no deadline imposed.
    long connectTimeout = config.getConnectTimeoutMillis();
    boolean connected;

    try {
      if ( connectTimeout > 0 ) {
        connected = cf.await( connectTimeout );
      } else {
        connected = cf.await();
      }
    } catch ( IOException e ) {
      throw new SshConnectionException( "SSH connection failed during await", e );
    }

    if ( !connected ) {
      if ( connectTimeout > 0 ) {
        throw new SshTimeoutException( "SSH connection timed out after " + connectTimeout + "ms" );
      }
      throw new SshTimeoutException( "SSH connection failed while waiting with no configured timeout" );
    }

    if ( !cf.isConnected() ) {
      Throwable cause = cf.getException();
      throw new SshConnectionException( "SSH connection failed", cause );
    }
  }

  private ClientSession establishSession( ConnectFuture cf ) throws SshConnectionException {
    ClientSession s = cf.getSession();

View on GitHub (pinned to f3058517a1)