{"record":{"id":"ad7c1e2a419e8d8a","repo":"pentaho/pentaho-kettle","slug":"ssh-error-privatekeynotexist","errorCode":"SSH.Error.PrivateKeyNotExist","errorMessage":"SSH.Error.PrivateKeyNotExist","messagePattern":"SSH\\.Error\\.PrivateKeyNotExist","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/ssh/SSHData.java","lineNumber":192,"sourceCode":"      config.authType( SshConfig.AuthType.PASSWORD ).password( password );\n    }\n  }\n\n  /**\n   * Configures key-based authentication using secure in-memory key handling.\n   * This avoids writing sensitive key data to temporary files on the filesystem.\n   */\n  private static void configureKeyAuthentication( SshConfig config, Bowl bowl,\n      String keyFilename, String passPhrase, VariableSpace space ) throws KettleException {\n\n    if ( Utils.isEmpty( keyFilename ) ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"SSH.Error.PrivateKeyFileMissing\" ) );\n    }\n\n    try {\n      FileObject keyFileObject = KettleVFS.getInstance( bowl ).getFileObject( keyFilename );\n      if ( !keyFileObject.exists() ) {\n        throw new KettleException( BaseMessages.getString( PKG, \"SSH.Error.PrivateKeyNotExist\", keyFilename ) );\n      }\n\n      // Read key file content into memory - no temporary file needed\n      FileContent keyFileContent = keyFileObject.getContent();\n      byte[] keyBytes;\n      try ( InputStream in = keyFileContent.getInputStream() ) {\n        keyBytes = in.readAllBytes();\n        if ( keyBytes.length == 0 ) {\n          throw new KettleException( BaseMessages.getString( PKG, \"SSH.Error.ProcessingKeyFile\", keyFilename ) );\n        }\n      }\n\n      // Configure SSH with in-memory key content - secure approach\n      config.authType( SshConfig.AuthType.PUBLIC_KEY ).keyContent( keyBytes );\n\n      if ( !Utils.isEmpty( passPhrase ) ) {\n        config.passphrase( space.environmentSubstitute( passPhrase ) );\n      }","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/ssh/SSHData.java#L174-L210","documentation":"SSH.Error.PrivateKeyNotExist is thrown by configureKeyAuthentication when a private key filename is provided but the file cannot be resolved through KettleVFS, i.e. the file does not exist at the given path. The step checks existence before reading the key so it can report a clear, specific error instead of an IO failure.","triggerScenarios":"The key file path entered in the step points to a non-existent file, or a variable in the path resolves to the wrong directory (e.g. different user home on the executing agent).","commonSituations":"Running the transformation on a server/node where the key file was never copied; wrong relative path (working directory differs); renamed or rotated key file.","solutions":["Correct the key file path to point at an existing file","Copy the private key to the machine/node where the transformation actually executes","Replace absolute paths with Kettle variables/parameters set per environment"],"exampleFix":"// before\nkeyFile = \"/home/jenkins/.ssh/id_rsa\"; // not present on worker node\n// after\n// copy the key first, or point to an existing one:\nkeyFile = \"/opt/pentaho/keys/deploy_key\";","handlingStrategy":"validation","validationCode":"java.io.File f = new java.io.File(environmentSubstitute(keyFileField));\nif (!f.isFile()) {\n  throw new IllegalStateException(\"Private key not found: \" + f.getAbsolutePath());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify the key exists on every node that runs the transformation","Avoid relative paths; use absolute or variable-based paths","Include key deployment in provisioning/CI setup"],"tags":["ssh","authentication","file-not-found"],"backgroundTag":"file-not-found","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"}