pentaho/pentaho-kettle · error · SshAuthenticationException
Failed to load SSH key
Error message
Failed to load SSH key
What it means
tryPublicKeyAuthentication wraps any IOException or GeneralSecurityException from loading/using the key pair into SshAuthenticationException('Failed to load SSH key'). The private key material could not be read, decrypted, or parsed before authentication could even be attempted.
Solutions
- Verify the key file exists, is readable, and is a supported format (OpenSSH/PEM, not PuTTY .ppk)
- Correct the passphrase — an encrypted key needs its passphrase in config
- Convert the key: ssh-keygen -p -m PEM -f id_rsa if the parser rejects the format
- If using key content, paste the full key including BEGIN/END header lines
- Upgrade the SSHD library if the key uses a newer format (e.g. ed25519-sk)
Example fix
// before config.setKeyContent( Files.readString( Path.of( "id_rsa" ) ).trim() ); // header stripped breaks parse // after config.setKeyContent( Files.readString( Path.of( "id_rsa" ) ) ); // keep full PEM including BEGIN/END lines
Defensive patterns
Strategy: validation
Validate before calling
// validate key before connect()
String key = config.getKeyContent() != null ? config.getKeyContent() : Files.readString( Path.of( keyPath ) );
if ( !key.contains( "BEGIN" ) || !key.contains( "PRIVATE KEY" ) ) {
throw new IllegalArgumentException( "Key is not a valid PEM/OpenSSH private key" );
}
if ( key.contains( "ENCRYPTED" ) && ( config.getPassphrase() == null || config.getPassphrase().isEmpty() ) ) {
throw new IllegalArgumentException( "Key is encrypted but no passphrase configured" );
} Try / catch
try { conn.connect(); }
catch ( SshAuthenticationException e ) {
if ( e.getMessage().contains( "Failed to load SSH key" ) ) {
log.error( "Key load failed: check format (PEM/OpenSSH, not .ppk), passphrase, and file readability", e.getCause() );
} else throw e;
} Prevention
- Use ssh-keygen -p -m PEM to convert keys the parser rejects
- Never paste .ppk files; convert PuTTY keys to OpenSSH format first
- Store the passphrase alongside the key config when keys are encrypted
- Check key file permissions (readable by the Pentaho process user)
When it happens
Trigger: Key content (in-memory) or key file is malformed/unsupported format, the passphrase is wrong or missing for an encrypted key, or the key file path is unreadable — raised inside loadKeysIntoSession/KeyPairProvider usage.
Common situations: PEM vs OpenSSH new-format keys not supported by the bundled SSHD version; wrong passphrase; key file permissions; empty key content field in the connection dialog; PKCS#8/PPK formats.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Failed to parse SSH key content
- Password authentication failed
- SFTPPUT.Error.Connection
- SSH authentication failed
- SSH connection failed -
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/dbb58ba59ee3a8fe.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/core/ssh/mina/MinaSshConnection.java:320
log( DEBUG, "Skipping public key authentication - not configured" );
return false;
}
log( DEBUG, "Attempting SSH public key authentication" );
try {
KeyPairProvider keyPairProvider = loadKeyPairProvider();
if ( keyPairProvider == null ) {
return false;
}
configurePassphrase( keyPairProvider );
loadKeysIntoSession( keyPairProvider );
return performPublicKeyAuth();
} catch ( IOException | GeneralSecurityException e ) {
log( ERROR, "SSH public key authentication error: " + e.getMessage(), e );
throw new SshAuthenticationException( "Failed to load SSH key", e );
}
}
private KeyPairProvider loadKeyPairProvider() {
if ( config.getKeyContent() != null ) {
log( DEBUG, "Using in-memory SSH key content" );
return createInMemoryKeyProvider( config.getKeyContent() );
}
if ( config.getKeyPath() != null ) {
log( DEBUG, "Loading SSH key from file: " + config.getKeyPath() );
Path key = config.getKeyPath();
if ( !Files.exists( key ) ) {
log( ERROR, "SSH key file does not exist: " + key );
return null;
}
return new FileKeyPairProvider( List.of( key ) );
}View on GitHub (pinned to f3058517a1)