{"record":{"id":"a72089b2fadabc3a","repo":"pentaho/pentaho-kettle","slug":"unable-to-list-jar-files-in-plugin-folder-folder","errorCode":null,"errorMessage":"Unable to list jar files in plugin folder '${folder}'","messagePattern":"Unable to list jar files in plugin folder '(.+?)'","errorType":"exception","errorClass":"KettleFileException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/plugins/PluginFolder.java","lineNumber":136,"sourceCode":"      FileObject folderObject = KettleVFS.getInstance( DefaultBowl.getInstance() ).getFileObject( this.getFolder() );\n\n      return folderObject.findFiles( new FileSelector() {\n        @Override\n        public boolean traverseDescendents( FileSelectInfo fileSelectInfo ) throws Exception {\n          FileObject fileObject = fileSelectInfo.getFile();\n          String folder = fileObject.getName().getBaseName();\n          FileObject kettleIgnore = fileObject.getChild( \".kettle-ignore\" );\n          return includeLibJars || ( kettleIgnore == null && !\"lib\".equals( folder ) );\n        }\n\n        @Override\n        public boolean includeFile( FileSelectInfo fileSelectInfo ) throws Exception {\n          FileObject file = fileSelectInfo.getFile();\n          return file.isFile() && file.toString().endsWith( \".jar\" );\n        }\n      } );\n    } catch ( Exception e ) {\n      throw new KettleFileException( \"Unable to list jar files in plugin folder '\" + toString() + \"'\", e );\n    }\n  }\n\n  /**\n   * @return the folder\n   */\n  @Override\n  public String getFolder() {\n    return folder;\n  }\n\n  /**\n   * @param folder\n   *          the folder to set\n   */\n  public void setFolder( String folder ) {\n    this.folder = folder;\n  }","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/plugins/PluginFolder.java#L118-L154","documentation":"PluginFolder.findJarFiles uses Apache VFS to list *.jar files in the configured plugin folder, wrapping failures in KettleFileException. This means the folder could not be read or iterated (does not exist, is not a directory, or I/O/permission failure), so no plugin jars could be discovered.","triggerScenarios":"findJarFiles (called by libFiles/recursive scan) throws when VFS's FileObject.getChildren()/listFiles on the folder path raises any Exception — folder missing, path is a file, no read permission, or an invalid/unsupported VFS URI.","commonSituations":"KETTLE_PLUGIN_FOLDER or plugin folder configuration points to a directory that doesn't exist or was renamed; wrong path separator/URI scheme passed to PluginFolder; read permissions missing on the plugin directory (common in containerized installs); folder deleted after startup config was written.","solutions":["Verify the plugin folder path exists and is a directory: ls <folder> (or the configured KETTLE_PLUGIN_FOLDERS value).","Fix the path/URI passed to PluginFolder (use an absolute path; check for typos and correct separators).","Grant the process read+execute permission on the folder (chmod/chown).","Check the nested cause exception in the KettleFileException for the underlying VFS/I/O reason."],"exampleFix":"// before\nPluginFolder folder = new PluginFolder(\"/opt/pentaho/plugns\", false, true); // typo path\n\n// after\nPluginFolder folder = new PluginFolder(\"/opt/pentaho/plugins\", false, true);\nFile dir = new File(\"/opt/pentaho/plugins\");\nif (!dir.isDirectory()) throw new IllegalStateException(\"Missing plugin folder: \" + dir);","handlingStrategy":"validation","validationCode":"File dir = new File(folderPath);\nif (!dir.isDirectory()) throw new IllegalStateException(\"Not a directory: \" + folderPath);\nif (!dir.canRead()) throw new IllegalStateException(\"Not readable: \" + folderPath);","typeGuard":"static boolean isReadableDirectory(java.io.File f) {\n  return f != null && f.isDirectory() && f.canRead();\n}","tryCatchPattern":"try {\n  jars = pluginFolder.findJarFiles(true);\n} catch (KettleFileException e) {\n  log.error(\"Plugin folder unreadable: \" + pluginFolder + \" cause: \" + e.getCause(), e);\n}","preventionTips":["Validate plugin folder paths at startup before scanning.","Use absolute paths and avoid manual URI string building.","Ensure container/deployment scripts create plugin directories with correct permissions.","Check the nested cause of KettleFileException to distinguish missing vs permission issues."],"tags":["kettle","plugins","filesystem","io"],"backgroundTag":"directory-not-found","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"}