{"record":{"id":"d8ecb62d6250732c","repo":"pentaho/pentaho-kettle","slug":"password-authentication-failed","errorCode":null,"errorMessage":"Password authentication failed","messagePattern":"Password authentication failed","errorType":"exception","errorClass":"SshAuthenticationException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSshConnection.java","lineNumber":415,"sourceCode":"\n      AuthFuture authFuture = session.auth();\n      long timeout = config.getConnectTimeoutMillis();\n      // PDI-20898: verify(0L) throws TimeoutException immediately; use no-arg verify() for infinite wait.\n      boolean success = ( timeout > 0 ? authFuture.verify( timeout ) : authFuture.verify() ).isSuccess();\n\n      if ( success ) {\n        log( DEBUG, \"SSH password authentication successful\" );\n      } else {\n        log( DEBUG, \"SSH password authentication failed\" );\n        if ( authFuture.getException() != null ) {\n          log( DEBUG, \"Authentication failure reason: \" + authFuture.getException().getMessage() );\n        }\n      }\n\n      return success;\n    } catch ( IOException e ) {\n      log( ERROR, \"SSH password authentication error: \" + e.getMessage(), e );\n      throw new SshAuthenticationException( \"Password authentication failed\", e );\n    }\n  }\n\n  private void configureSessionHeartbeat() {\n    if ( config.getCommandTimeoutMillis() > 0 ) {\n      int intervalSeconds = (int) Math.max( 1, config.getCommandTimeoutMillis() / 1000 );\n      // session implements SessionHeartbeatController\n      ( (SessionHeartbeatController) session ).setSessionHeartbeat( SessionHeartbeatController.HeartbeatType.IGNORE,\n        TimeUnit.SECONDS, intervalSeconds );\n    }\n  }\n\n  @Override\n  public ExecResult exec( String command, long timeoutMs ) throws SshConnectionException {\n    try {\n      ByteArrayOutputStream stdout = new ByteArrayOutputStream();\n      ByteArrayOutputStream stderr = new ByteArrayOutputStream();\n      int exit;","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSshConnection.java#L397-L433","documentation":"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.","triggerScenarios":"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.","commonSituations":"Server drops connections after failed attempts (fail2ban, MaxAuthTries); network drop during handshake; server requiring keyboard-interactive rather than 'password' method.","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"],"exampleFix":"// before\nconn.connect(); // retries same bad password, eventually tripping fail2ban\n// after\nif ( !tryManualSshLogin( host, user, password ) ) { throw new IllegalArgumentException( \"Credentials rejected\" ); } // pre-validate\nconn.connect();","handlingStrategy":"try-catch","validationCode":"// verify password auth works before running\nProcess p = new ProcessBuilder( \"sshpass\", \"-e\", \"ssh\", \"-o\", \"StrictHostKeyChecking=no\",\n    user + \"@\" + host, \"true\" );\np.environment().put( \"SSHPASS\", password );\nboolean ok = p.start().waitFor() == 0;","typeGuard":null,"tryCatchPattern":"try { conn.connect(); }\ncatch ( SshAuthenticationException e ) {\n  if ( e.getCause() instanceof IOException ) { log.error( \"Transport error during password auth; check server bans/drops\", e.getCause() ); }\n  else throw e;\n}","preventionTips":["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"],"tags":["ssh","authentication","password","io"],"backgroundTag":"authentication-required","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"}