pentaho/pentaho-kettle · error · KettleException

GPG.GPGFilenameNotFound

Error message

GPG.GPGFilenameNotFound

What it means

Thrown by the GPG constructor when the configured GPG executable path resolves to a VFS FileObject that does not exist. The check happens after the filename is confirmed non-empty, validating the binary actually exists before use.

Solutions

  1. Locate the real gpg binary (which gpg / where gpg) and set that exact path in the entry configuration.
  2. Install GnuPG if absent (apt/yum/brew/Windows installer).
  3. Check the path for typos and that any variables in it resolve correctly on the executing node.
  4. Ensure the path is valid on the machine that actually runs the job (agents/slaves may differ from the designer machine).

Example fix

// before
GPG gpg = new GPG( bowl, "/usr/local/bin/gpg", log ); // binary not there
// after
String gpgPath = "/usr/bin/gpg"; // verified with: which gpg
GPG gpg = new GPG( bowl, gpgPath, log );
Defensive patterns

Strategy: validation

Validate before calling

String gpgPath = "/usr/bin/gpg";
java.io.File f = new java.io.File( gpgPath );
if ( !f.exists() ) throw new IllegalArgumentException( "GPG binary not found at " + gpgPath );

Type guard

boolean gpgBinaryExists( String p ) { return p != null && new java.io.File( p ).isFile(); }

Try / catch

try {
  GPG gpg = new GPG( bowl, gpgPath, log );
} catch ( KettleException e ) {
  if ( e.getMessage().contains( "GPGFilenameNotFound" ) ) {
    logError( "Install GnuPG or fix the configured executable path: " + gpgPath );
  }
}

Prevention

When it happens

Trigger: new GPG(bowl, gpgFilename, log) where KettleVFS.getFileObject(getGpgExeFile()).exists() returns false — the path points to a missing file, or the VFS scheme/variables resolve to a non-existent location.

Common situations: GnuPG not installed or installed at a different path; path configured on Windows (gpg.exe) but job runs on Linux; typo in path; GPG installed via Homebrew (/opt/homebrew/bin/gpg) but config points to /usr/bin/gpg.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/d187e21d52aadf66. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/job/entries/pgpencryptfiles/GPG.java:123

   * @param logInterface
   *          LogChannelInterface
   * @throws KettleException
   */
  public GPG( Bowl bowl, String gpgFilename, LogChannelInterface logInterface ) throws KettleException {
    this.log = logInterface;
    this.gpgexe = gpgFilename;
    // Let's check GPG filename
    if ( Utils.isEmpty( getGpgExeFile() ) ) {
      // No filename specified
      throw new KettleException( BaseMessages.getString( PKG, "GPG.GPGFilenameMissing" ) );
    }
    // We have a filename, we need to check
    FileObject file = null;
    try {
      file = KettleVFS.getInstance( bowl ).getFileObject( getGpgExeFile() );

      if ( !file.exists() ) {
        throw new KettleException( BaseMessages.getString( PKG, "GPG.GPGFilenameNotFound" ) );
      }
      // The file exists
      if ( !file.getType().equals( FileType.FILE ) ) {
        throw new KettleException( BaseMessages.getString( PKG, "GPG.GPGNotAFile", getGpgExeFile() ) );
      }

      // Ok we have a real file
      // Get the local filename
      this.gpgexe = KettleVFS.getFilename( file );

    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, "GPG.ErrorCheckingGPGFile", getGpgExeFile() ), e );
    } finally {
      try {
        if ( file != null ) {
          file.close();
        }
      } catch ( Exception e ) {

View on GitHub (pinned to f3058517a1)