pentaho/pentaho-kettle · error · KettleException
Plugin's plugin.properties file could not be read.
Error message
Plugin's plugin.properties file could not be read.
What it means
PluginInterface.getPluginProperties loads the plugin's plugin.properties file from disk into a Properties object. If pluginPropsFile exists (non-null) but reading it fails — I/O error, permission denied, or malformed stream — a KettleException with this message is thrown, wrapping the underlying cause.
Solutions
- Check the wrapped cause exception and verify the plugin.properties path exists and is readable (ls -l).
- Fix file permissions on plugin.properties for the user running Pentaho/Kettle.
- Reinstall/re-extract the plugin so a valid plugin.properties is present.
- Rebuild the plugin jar/zip ensuring plugin.properties is included at the plugin root and not corrupted.
Example fix
// before
File props = new File(pluginFolder, "plugin.properties"); // permissions 600, other user
// after
File props = new File(pluginFolder, "plugin.properties");
if (!props.canRead()) {
throw new IllegalStateException("Not readable: " + props);
}
// and on deploy: chmod 644 plugin.properties Defensive patterns
Strategy: try-catch
Validate before calling
File props = plugin.getPluginPropsFile();
if (props != null && !(props.isFile() && props.canRead())) {
throw new IllegalStateException("plugin.properties unreadable at " + props);
} Type guard
static boolean isReadableFile(java.io.File f) {
return f != null && f.isFile() && f.canRead();
} Try / catch
try {
props = plugin.getPluginProperties();
} catch (KettleException e) {
log.error("Failed to read plugin.properties: " + e.getCause(), e);
props = new Properties(); // degrade gracefully
} Prevention
- Ship a valid plugin.properties in every plugin build and verify in CI packaging tests.
- Deploy plugins as the same user that runs Pentaho, or chmod 644 resource files.
- Avoid editing plugin.properties in place on production servers; redeploy instead.
- Inspect e.getCause() to differentiate missing file vs IO errors.
When it happens
Trigger: getPluginProperties() is called on a PluginInterface whose pluginPropsFile points to an existing file that cannot be loaded: unreadable permissions, a directory at that path, file deleted between existence check and load, or a FileInputStream creation/IO failure.
Common situations: plugin.properties has restrictive permissions after deployment; file was packaged incorrectly (partial/zero-length or corrupt); the plugin folder was moved without updating the plugin's paths; on some systems the file is a broken symlink.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Unable to list jar files in plugin folder
- Error opening new file
- ex.getMessage()
- GetSubFolders.Exception.MissingFiles
- GetSubFolders.Exception.NoAccessibleFiles
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/55593a3c3cbc6d70.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/plugins/PluginInterface.java:203
}
/**
* @return Plugin properties
* Returns a Properties object containing any properties in a plugin.properties file
* in the plugin directopry. The method will return null if the plugin.properties
* does not exist.
**/
default Properties getPluginProperties() throws KettleException {
String pluginPropsFilePath = getPluginDirectory().getPath() + "/plugin.properties";
File pluginPropsFile = new File( pluginPropsFilePath );
if ( !pluginPropsFile.exists() ) {
return null;
}
Properties pluginProps = new Properties();
try {
pluginProps.load( new FileInputStream( pluginPropsFile ) );
} catch ( Exception e ) {
throw new KettleException( "Plugin's plugin.properties file could not be read.", e );
}
return pluginProps;
}
/**
* @return a boolean that indicates if this plugin id is deprecated. The getSuggestion()
* should be used when deprecated to indicate an id of a replacement plugin id.
*/
default boolean isDeprecated() {
return false;
}
}
View on GitHub (pinned to f3058517a1)