pentaho/pentaho-kettle · error · SshAuthenticationException
Password authentication failed
Error message
Password authentication failed
What it means
tryPasswordAuthentication wraps IOException from the session.auth() call into SshAuthenticationException('Password authentication failed'). Unlike a plain auth rejection, this wraps a transport-level IO error during the password exchange (dropped connection, stream failure) — but the resulting symptom for callers is the same: password auth could not complete.
Solutions
- Check server-side blocks (fail2ban) and MaxAuthTries then retry
- Verify the password is correct with a manual ssh login
- Enable keyboard-interactive/PAM compatibility on the server or use key auth instead
- Inspect the wrapped IOException cause in logs for the transport reason
- Ensure the connection isn't being closed by a proxy/load balancer mid-auth
Example fix
// before
conn.connect(); // retries same bad password, eventually tripping fail2ban
// after
if ( !tryManualSshLogin( host, user, password ) ) { throw new IllegalArgumentException( "Credentials rejected" ); } // pre-validate
conn.connect(); Defensive patterns
Strategy: try-catch
Validate before calling
// verify password auth works before running
Process p = new ProcessBuilder( "sshpass", "-e", "ssh", "-o", "StrictHostKeyChecking=no",
user + "@" + host, "true" );
p.environment().put( "SSHPASS", password );
boolean ok = p.start().waitFor() == 0; Try / catch
try { conn.connect(); }
catch ( SshAuthenticationException e ) {
if ( e.getCause() instanceof IOException ) { log.error( "Transport error during password auth; check server bans/drops", e.getCause() ); }
else throw e;
} Prevention
- Limit password attempts to avoid fail2ban/MaxAuthTries locks
- Prefer public key authentication
- Enable keyboard-interactive support on the server if PAM is required
- Check sshd logs when auth mysteriously fails
When it happens
Trigger: session.auth(...).await() or writing the password raises IOException during authenticateSession — e.g. the server closes the connection mid-auth or the session buffer fails.
Common situations: Server drops connections after failed attempts (fail2ban, MaxAuthTries); network drop during handshake; server requiring keyboard-interactive rather than 'password' method.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Failed to check if path is directory:
- Failed to download file:
- Failed to get file size:
- Failed to load SSH key
- Failed to parse SSH key content
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/d8ecb62d6250732c.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSshConnection.java:415
AuthFuture authFuture = session.auth();
long timeout = config.getConnectTimeoutMillis();
// PDI-20898: verify(0L) throws TimeoutException immediately; use no-arg verify() for infinite wait.
boolean success = ( timeout > 0 ? authFuture.verify( timeout ) : authFuture.verify() ).isSuccess();
if ( success ) {
log( DEBUG, "SSH password authentication successful" );
} else {
log( DEBUG, "SSH password authentication failed" );
if ( authFuture.getException() != null ) {
log( DEBUG, "Authentication failure reason: " + authFuture.getException().getMessage() );
}
}
return success;
} catch ( IOException e ) {
log( ERROR, "SSH password authentication error: " + e.getMessage(), e );
throw new SshAuthenticationException( "Password authentication failed", e );
}
}
private void configureSessionHeartbeat() {
if ( config.getCommandTimeoutMillis() > 0 ) {
int intervalSeconds = (int) Math.max( 1, config.getCommandTimeoutMillis() / 1000 );
// session implements SessionHeartbeatController
( (SessionHeartbeatController) session ).setSessionHeartbeat( SessionHeartbeatController.HeartbeatType.IGNORE,
TimeUnit.SECONDS, intervalSeconds );
}
}
@Override
public ExecResult exec( String command, long timeoutMs ) throws SshConnectionException {
try {
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
ByteArrayOutputStream stderr = new ByteArrayOutputStream();
int exit;View on GitHub (pinned to f3058517a1)