{"record":{"id":"0eaa3e80334f0419","repo":"pentaho/pentaho-kettle","slug":"gpg-exceptionwait","errorCode":null,"errorMessage":"GPG.ExceptionWait","messagePattern":"GPG\\.ExceptionWait","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/job/entries/pgpencryptfiles/GPG.java","lineNumber":214,"sourceCode":"        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 );\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  }","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/job/entries/pgpencryptfiles/GPG.java#L196-L232","documentation":"KettleException with key GPG.ExceptionWait is thrown by GPG.execGnuPG when p.waitFor() or joining the stdout/stderr reader threads is interrupted (InterruptedException). The GPG entry runs gpg asynchronously and blocks waiting for completion; if the executing thread (e.g. a Kettle job thread being cancelled/stopped) is interrupted, the wait is aborted and this exception wraps the interrupt.","triggerScenarios":"Calling any of decryptFile, encryptFile, signAndEncryptFile, signFile, verifySignature, or verifyDetachedSignature while the running thread receives an interrupt during p.waitFor() or psr_stdout.join()/psr_stderr.join().","commonSituations":"User stops/cancels a Kettle job or transformation; JVM shutdown hooks interrupt worker threads; a timeout watchdog interrupts long-running gpg operations on very large files.","solutions":["Avoid stopping the job mid-GPG operation, or accept that cancellation surfaces as this exception.","Increase any watchdog/timeout so gpg has time to finish large encrypt/sign operations.","Catch KettleException, check the cause is InterruptedException, and restore the interrupt flag (Thread.currentThread().interrupt()) if rethrowing is not desired.","Investigate which component interrupts the thread (job executor, scheduler, shutdown)."],"exampleFix":"// before\n} catch ( KettleException ke ) {\n  logError( ke.getMessage() );\n}\n// after\n} catch ( KettleException ke ) {\n  if ( ke.getCause() instanceof InterruptedException ) {\n    Thread.currentThread().interrupt();\n  }\n  logError( ke.getMessage() );\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  gpg.encryptFile(file, userId, destFile, true);\n} catch (KettleException ke) {\n  if (ke.getCause() instanceof InterruptedException) {\n    Thread.currentThread().interrupt(); // restore flag, do not blindly retry\n  }\n}","preventionTips":["Do not stop/cancel jobs during GPG operations","Allow sufficient time for large-file operations","Identify watchdog components that interrupt worker threads"],"tags":["gpg","interrupt","thread","process"],"backgroundTag":"thread-interrupted","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"}