pentaho/pentaho-kettle · error · SshConnectionException
Failed to execute command
Error message
Failed to execute command: ${command} What it means
The generic catch-all in exec converts any unexpected Exception (channel open failure, IO error while streaming output, session closed, etc.) into SshConnectionException('Failed to execute command: <command>') with the original exception attached. It means command execution failed for a reason not classified as timeout or interruption.
Solutions
- Check the cause attached to the exception for the true failure reason
- Ensure the connection is still open ( isConnected() ) before calling exec; reconnect if needed
- Increase server ClientAliveInterval / client heartbeat to keep long sessions alive
- Validate/quote the command string (avoid unescaped special characters)
- Reconnect and retry once on transient session-closed causes
Example fix
// before
if ( !conn.isConnected() ) { /* proceed anyway */ }
ExecResult r = conn.exec( cmd );
// after
if ( !conn.isConnected() ) { conn.connect(); conn.authenticate(); } // re-establish session
ExecResult r = conn.exec( cmd ); Defensive patterns
Strategy: try-catch
Validate before calling
// guard before exec
if ( conn == null || !conn.isConnected() ) {
throw new IllegalStateException( "SSH session not connected; call connect() first" );
}
if ( command == null || command.trim().isEmpty() ) {
throw new IllegalArgumentException( "Command must be non-empty" );
} Try / catch
try { result = conn.exec( cmd ); }
catch ( SshConnectionException e ) {
if ( e.getMessage().startsWith( "Failed to execute command" ) && e.getCause() != null ) {
log.error( "exec of '{}' failed: {}", cmd, e.getCause().toString() );
reconnectAndRetryOnce( conn, cmd ); // transient session-closed handling
} else throw e;
} Prevention
- Always check isConnected() before exec; reconnect on failure
- Configure heartbeats to keep sessions alive during long waits
- Quote/escape shell metacharacters in command strings
- Inspect the attached cause — the generic message hides the real reason
When it happens
Trigger: Any non-timeout exception inside exec: channel could not be opened, session already disconnected/closed, IOException reading stdout/stderr streams, or command string rejected by the session.
Common situations: Calling exec after the connection was closed or dropped; session timed out server-side (ClientAliveInterval) before the command ran; command too long or containing characters the shell mishandles.
Related errors
- Command execution timed out after
- Attempting to create PDI Repository with no Active…
- Browser session authentication requested but no JSESSIONID…
- Command execution was interrupted
- Failed to check if path is directory:
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/1b184ce9f3a0e2ee.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSshConnection.java:472
Thread.sleep( 100 );
ex = ch.getExitStatus();
}
exit = ex == null ? -1 : ex;
} else {
// Timeout occurred
throw new SshTimeoutException( "Command execution timed out after " + timeoutMs + "ms" );
}
}
String outStr = stdout.toString( StandardCharsets.UTF_8 );
String errStr = stderr.toString( StandardCharsets.UTF_8 );
return new ExecResult( outStr, errStr, outStr + errStr, exit, exit != 0 );
} catch ( SshTimeoutException e ) {
throw e; // Re-throw timeout exceptions as-is
} catch ( InterruptedException e ) {
Thread.currentThread().interrupt(); // Restore interrupted status
throw new SshConnectionException( "Command execution was interrupted", e );
} catch ( Exception e ) {
throw new SshConnectionException( "Failed to execute command: " + command, e );
}
}
@Override
public ExecResult exec( String command ) throws SshConnectionException {
return exec( command, config.getCommandTimeoutMillis() );
}
@Override
public SftpSession openSftp() throws SshConnectionException {
try {
var factory = SftpClientFactory.instance();
var sftp = factory.createSftpClient( session );
return new MinaSftpSession( sftp );
} catch ( Exception e ) {
throw new SftpException( "Failed to open SFTP session", e );
}
}View on GitHub (pinned to f3058517a1)