pentaho/pentaho-kettle · error · KettleException

GPG.GPGNotAFile

Error message

GPG.GPGNotAFile

What it means

Thrown by the GPG constructor when the configured GPG path exists in VFS but its FileType is not FileType.FILE — i.e. it is a directory or another non-regular file. The entry requires a real executable file path.

Solutions

  1. Point the configuration at the executable file itself, not its parent directory (e.g. /usr/bin/gpg, C:\Program Files\GnuPG\bin\gpg.exe).
  2. Verify with ls -l or dir that the configured path is a regular file.
  3. Fix any variable that resolves to a directory path.

Example fix

// before
String gpgPath = "/usr/bin"; // directory
// after
String gpgPath = "/usr/bin/gpg"; // the executable file
GPG gpg = new GPG( bowl, gpgPath, log );
Defensive patterns

Strategy: validation

Validate before calling

java.io.File f = new java.io.File( gpgPath );
if ( f.exists() && !f.isFile() ) {
  throw new IllegalArgumentException( "GPG path is not a file (directory?): " + gpgPath );
}

Type guard

boolean isRegularFile( 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( "GPGNotAFile" ) ) {
    logError( "Point configuration at the gpg executable itself, not a directory: " + gpgPath );
  }
}

Prevention

When it happens

Trigger: new GPG(bowl, gpgFilename, log) where file.exists() is true but file.getType() != FileType.FILE — typically the configured path points at a directory (e.g. /usr/bin or GnuPG's install folder) instead of the executable.

Common situations: User configured the GnuPG installation directory instead of the binary; on Windows configured C:\Program Files\GnuPG\bin without \gpg.exe; variable expansion truncated the filename.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

  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 ) {
        // Ignore close errors
      }
    }
  }

View on GitHub (pinned to f3058517a1)