pentaho/pentaho-kettle · error · KettlePluginException
PLUGINREGISTRY006
PLUGINREGISTRY006
Error message
Malformed URL
What it means
KettlePluginException thrown by PluginRegistry.createClassLoader when constructing the URLClassLoader for a plugin fails because one of the plugin's jar/lib URLs is malformed. The registry converts each plugin folder/jar path into java.net.URL objects; an invalid URL string (bad syntax, unescaped characters, invalid protocol) triggers MalformedURLException which is wrapped with code PLUGINREGISTRY006.
Solutions
- Fix the plugin path so it is a valid URL: escape spaces (%20) or use folder.toURI().toURL() instead of new URL(folderPath)
- Check the plugin folder/jar actually exists and the path in the plugin configuration is correct
- Move the plugin to a directory without spaces or special characters
- Inspect the wrapped MalformedURLException cause for the exact offending URL
Example fix
// before
URL url = new URL("file:/opt/pentaho/plugins/my plugin/lib/x.jar");
// after
URL url = new File("/opt/pentaho/plugins/my plugin/lib/x.jar").toURI().toURL(); Defensive patterns
Strategy: try-catch
Validate before calling
String p = "/opt/pentaho/plugins/my plugin";
java.io.File f = new java.io.File(p);
if ( !f.exists() ) throw new IllegalStateException("plugin folder missing: " + p);
java.net.URL url = f.toURI().toURL(); // never throws MalformedURLException for existing files Type guard
static boolean isSafePluginPath(String p) {
return p != null && !p.isEmpty() && new java.io.File(p).exists();
} Try / catch
try {
ClassLoader ucl = PluginRegistry.init().createClassLoader(plugin, null);
} catch ( KettlePluginException e ) {
// e.getMessage() contains PLUGINREGISTRY006; getCause() is the MalformedURLException
log.error("Bad plugin URL for " + plugin.getName() + ": " + e.getCause().getMessage());
} Prevention
- Use File.toURI().toURL() instead of new URL(pathString) for plugin locations
- Avoid spaces/non-ASCII characters in plugin install directories
- Validate plugin folder paths at startup before registering plugins
- Log the resolved URLs of every plugin jar during deployment checks
When it happens
Trigger: Calling PluginRegistry.createClassLoader (directly or via plugin initialization) when a plugin's jarFiles list or plugin folder yields a URL that java.net.URL cannot parse - e.g. a path with spaces or illegal characters not escaped, or an unsupported protocol scheme.
Common situations: Plugin installed in a directory whose name contains spaces or non-ASCII characters; manually configured plugin paths in kettle.properties or plugin.xml with typos; Windows-style paths passed as URLs; a plugin jar moved/deleted leaving a stale relative path.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- PLUGINREGISTRY008
- Error creating plugin class
- Unable to get instance of plugin type
- A server socket allocation always has to accompanied by a…
- A server socket allocation always has to accompanied by a…
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/c8b92c618f092a6d.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/plugins/PluginRegistry.java:996
}
}
ucl = createClassLoader( plugin );
classLoaders.put( plugin, ucl ); // save for later use...
inverseClassLoaderLookup.computeIfAbsent( ucl, k -> new HashSet<>() ).add( plugin );
}
}
}
}
}
} finally {
lock.writeLock().unlock();
}
// Load the class.
return ucl;
}
} catch ( MalformedURLException e ) {
throw new KettlePluginException( BaseMessages.getString(
PKG, "PluginRegistry.RuntimeError.MalformedURL.PLUGINREGISTRY006" ), e );
} catch ( Throwable e ) {
e.printStackTrace();
throw new KettlePluginException( BaseMessages.getString(
PKG, "PluginRegistry.RuntimeError.UnExpectedCreatingClassLoader.PLUGINREGISTRY008" ), e );
}
}
/**
* Allows the tracking of plugins as they come and go.
*
* @param typeToTrack extension of PluginTypeInterface to track.
* @param listener receives notification when a plugin of the specified type is added/removed/modified
* @param <T> extension of PluginTypeInterface
*/
public <T extends PluginTypeInterface> void addPluginListener( Class<T> typeToTrack, PluginTypeListener listener ) {
lock.writeLock().lock();
try {View on GitHub (pinned to f3058517a1)