{"record":{"id":"59d74db0aaeb4563","repo":"pentaho/pentaho-kettle","slug":"gpg-gpgnotafile","errorCode":null,"errorMessage":"GPG.GPGNotAFile","messagePattern":"GPG\\.GPGNotAFile","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/job/entries/pgpencryptfiles/GPG.java","lineNumber":127,"sourceCode":"  public GPG( Bowl bowl, String gpgFilename, LogChannelInterface logInterface ) throws KettleException {\n    this.log = logInterface;\n    this.gpgexe = gpgFilename;\n    // Let's check GPG filename\n    if ( Utils.isEmpty( getGpgExeFile() ) ) {\n      // No filename specified\n      throw new KettleException( BaseMessages.getString( PKG, \"GPG.GPGFilenameMissing\" ) );\n    }\n    // We have a filename, we need to check\n    FileObject file = null;\n    try {\n      file = KettleVFS.getInstance( bowl ).getFileObject( getGpgExeFile() );\n\n      if ( !file.exists() ) {\n        throw new KettleException( BaseMessages.getString( PKG, \"GPG.GPGFilenameNotFound\" ) );\n      }\n      // The file exists\n      if ( !file.getType().equals( FileType.FILE ) ) {\n        throw new KettleException( BaseMessages.getString( PKG, \"GPG.GPGNotAFile\", getGpgExeFile() ) );\n      }\n\n      // Ok we have a real file\n      // Get the local filename\n      this.gpgexe = KettleVFS.getFilename( file );\n\n    } catch ( Exception e ) {\n      throw new KettleException( BaseMessages.getString( PKG, \"GPG.ErrorCheckingGPGFile\", getGpgExeFile() ), e );\n    } finally {\n      try {\n        if ( file != null ) {\n          file.close();\n        }\n      } catch ( Exception e ) {\n        // Ignore close errors\n      }\n    }\n  }","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/job/entries/pgpencryptfiles/GPG.java#L109-L145","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Point the configuration at the executable file itself, not its parent directory (e.g. /usr/bin/gpg, C:\\Program Files\\GnuPG\\bin\\gpg.exe).","Verify with ls -l or dir that the configured path is a regular file.","Fix any variable that resolves to a directory path."],"exampleFix":"// before\nString gpgPath = \"/usr/bin\"; // directory\n// after\nString gpgPath = \"/usr/bin/gpg\"; // the executable file\nGPG gpg = new GPG( bowl, gpgPath, log );","handlingStrategy":"validation","validationCode":"java.io.File f = new java.io.File( gpgPath );\nif ( f.exists() && !f.isFile() ) {\n  throw new IllegalArgumentException( \"GPG path is not a file (directory?): \" + gpgPath );\n}","typeGuard":"boolean isRegularFile( String p ) { return p != null && new java.io.File( p ).isFile(); }","tryCatchPattern":"try {\n  GPG gpg = new GPG( bowl, gpgPath, log );\n} catch ( KettleException e ) {\n  if ( e.getMessage().contains( \"GPGNotAFile\" ) ) {\n    logError( \"Point configuration at the gpg executable itself, not a directory: \" + gpgPath );\n  }\n}","preventionTips":["Configure the full path to the executable, never its install directory.","On Windows include gpg.exe in the path.","Check variable expansion doesn't truncate the filename.","Verify with ls -l / dir that the path is a regular file."],"tags":["gpg","configuration","invalid-path"],"backgroundTag":"invalid-argument-value","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"}