{"record":{"id":"4079870e0736ca43","repo":"pentaho/pentaho-kettle","slug":"gpg-exception-existstatus","errorCode":null,"errorMessage":"GPG.Exception.ExistStatus","messagePattern":"GPG\\.Exception\\.ExistStatus","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/job/entries/pgpencryptfiles/GPG.java","lineNumber":219,"sourceCode":"          } catch ( Exception e ) {\n            // Ignore\n          }\n        }\n      }\n    }\n\n    try {\n      p.waitFor();\n\n      psr_stdout.join();\n      psr_stderr.join();\n    } catch ( InterruptedException i ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"GPG.ExceptionWait\" ), i );\n    }\n\n    try {\n      if ( p.exitValue() != 0 ) {\n        throw new KettleException( BaseMessages.getString( PKG, \"GPG.Exception.ExistStatus\", psr_stderr\n          .getString() ) );\n      }\n    } catch ( IllegalThreadStateException itse ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"GPG.ExceptionillegalThreadStateException\" ), itse );\n    } finally {\n      p.destroy();\n    }\n\n    retval = psr_stdout.getString();\n\n    return retval;\n\n  }\n\n  /**\n   * Decrypt a file\n   *\n   * @param cryptedFilename","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/job/entries/pgpencryptfiles/GPG.java#L201-L237","documentation":"KettleException with key GPG.Exception.ExistStatus is thrown by GPG.execGnuPG when the gpg process terminates with a non-zero exit code. The stderr produced by the gpg process is embedded in the message, so the actual GnuPG failure (bad passphrase, missing key, unreadable file) is reported there. This is the standard way external-command failures from GPG file operations surface.","triggerScenarios":"Any of decryptFile, encryptFile, signAndEncryptFile, signFile, verifySignature, verifyDetachedSignature invoking gpg which completes but returns exitValue() != 0.","commonSituations":"Wrong or missing passphrase; private/public key not in the keyring for the given userID; input file does not exist or is not readable; gpg version differences in accepted options; corrupted or non-GPG input to decrypt/verify.","solutions":["Read the stderr text in the exception message — it contains gpg's own diagnostic (e.g. 'No secret key', 'Bad passphrase').","Import/verify the required keys: gpg --list-keys / --list-secret-keys for the userID used by the entry.","Confirm the passphrase and userID configured in the JobPGPEncryptFiles entry match the keyring.","Check input/output file paths exist and are readable/writable by the user running Kettle."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before running the entry:\nProcess p = new ProcessBuilder(\"gpg\", \"--list-secret-keys\", userId).start();\nif (p.waitFor() != 0) throw new IllegalStateException(\"No signing key for \" + userId);\nif (!new java.io.File(inputPath).canRead()) throw new IllegalStateException(\"Input unreadable\");","typeGuard":null,"tryCatchPattern":"try {\n  gpg.decryptFile(file, userId, pass, destFile, true);\n} catch (KettleException ke) {\n  // message embeds gpg stderr — surface it to the operator\n  logger.error(\"gpg failed: \" + ke.getMessage());\n}","preventionTips":["Import required keys into the keyring gpg will use","Verify passphrase/userID in a test run before production","Ensure input/output paths are readable/writable by the Kettle user"],"tags":["gpg","process","exit-code","encryption"],"backgroundTag":"command-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"}