{"record":{"id":"166d6a5a88f288c5","repo":"pentaho/pentaho-kettle","slug":"gpg-exceptionwrite","errorCode":null,"errorMessage":"GPG.ExceptionWrite","messagePattern":"GPG\\.ExceptionWrite","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/job/entries/pgpencryptfiles/GPG.java","lineNumber":196,"sourceCode":"        p = Runtime.getRuntime().exec( command );\n      } else {\n        ProcessBuilder processBuilder = new ProcessBuilder( \"/bin/sh\", \"-c\", command );\n        p = processBuilder.start();\n      }\n    } catch ( IOException io ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"GPG.IOException\" ), io );\n    }\n\n    ProcessStreamReader psr_stdout = new ProcessStreamReader( p.getInputStream() );\n    ProcessStreamReader psr_stderr = new ProcessStreamReader( p.getErrorStream() );\n    psr_stdout.start();\n    psr_stderr.start();\n    if ( inputStr != null ) {\n      BufferedWriter out = new BufferedWriter( new OutputStreamWriter( p.getOutputStream() ) );\n      try {\n        out.write( inputStr );\n      } catch ( IOException io ) {\n        throw new KettleException( BaseMessages.getString( PKG, \"GPG.ExceptionWrite\" ), io );\n      } finally {\n        if ( out != null ) {\n          try {\n            out.close();\n          } 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 );","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/job/entries/pgpencryptfiles/GPG.java#L178-L214","documentation":"KettleException with key GPG.ExceptionWrite is thrown by GPG.execGnuPG when writing the passphrase (inputStr) to the GnuPG process's stdin fails with an IOException. GPG.java launches gpg as an external process and feeds the passphrase through a BufferedWriter on the process output stream; if the pipe is broken the write cannot proceed. This typically means the gpg process exited or was never started correctly before the passphrase could be delivered.","triggerScenarios":"Calling any of decryptFile, encryptFile, signAndEncryptFile, signFile, verifySignature, or verifyDetachedSignature when the underlying gpg process has terminated or its stdin pipe is broken, so out.write(inputStr) throws IOException.","commonSituations":"gpg binary path is wrong so the process died immediately; gpg crashed on bad arguments (e.g. malformed --passphrase-fd options); OS killed the process; passphrase contains characters that break the writer encoding setup.","solutions":["Verify the GnuPG executable location and that it runs (gpg --version) before invoking the job entry.","Check the gpg command-line arguments built in execGnuPG for malformed quoting (userID/filename with embedded quotes).","Confirm the passphrase/userID supplied to the entry are correct and non-empty; a bad gpg invocation can make the process exit before reading stdin.","Catch KettleException and log the stderr captured by psr_stderr to identify why gpg died."],"exampleFix":"// before\nout.write( inputStr );\n// after\nif ( inputStr != null ) {\n  out.write( inputStr );\n  out.flush();\n} else {\n  throw new KettleException( \"No passphrase supplied to GPG\" );\n}","handlingStrategy":"try-catch","validationCode":"Process check = new ProcessBuilder(\"gpg\", \"--version\").start();\nif (check.waitFor() != 0) throw new IllegalStateException(\"gpg not usable\");","typeGuard":null,"tryCatchPattern":"try {\n  gpg.signFile(file, userId, signedFile, true);\n} catch (KettleException ke) {\n  if (ke.getMessage().contains(\"GPG.ExceptionWrite\")) {\n    // gpg died before reading passphrase; log and re-run diagnostics\n  }\n}","preventionTips":["Verify gpg is installed and executable before running the entry","Keep filenames and userIDs free of quotes/special characters","Capture and log gpg stderr for diagnostics"],"tags":["gpg","io","process","kettle"],"backgroundTag":"broken-pipe","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"}