pentaho/pentaho-kettle · error · KettlePluginException
Unable to read the kettle XML config file
Error message
Unable to read the kettle XML config file: ${xmlFile} What it means
Once the native plugin XML input stream is obtained, registerNatives parses it via registerPlugins. If parsing raises KettleXMLException (malformed XML, unexpected structure), it is rethrown as KettlePluginException 'Unable to read the kettle XML config file'. The stream is always closed in the finally block. This indicates the plugin definition file exists but is unreadable/invalid.
Solutions
- Validate the XML file named in the message with an XML parser / xmllint and fix syntax errors.
- Restore the original plugin XML from a clean Pentaho install or jar if it was modified.
- If using a custom/alternative definition file, correct its structure to match the expected <plugins><plugin .../> schema.
- Check the wrapped cause for the exact XML parse error (line/column).
Example fix
// before <plugins><plugin id='x' class='Foo'></plugins> <!-- missing close tag --> // after <plugins><plugin id='x' class='Foo'></plugin></plugins>
Defensive patterns
Strategy: try-catch
Validate before calling
File xml = new File(xmlFile);
if (xml.exists()) {
try { new javax.xml.parsers.DocumentBuilderFactory().newDocumentBuilder().parse(xml); }
catch (Exception e) { throw new IllegalStateException("Invalid plugin XML: " + e.getMessage(), e); }
} Try / catch
try {
pluginType.searchPlugins();
} catch (KettlePluginException e) {
Throwable cause = e.getCause(); // KettleXMLException with parse details
log.logError("Malformed plugin XML: " + (cause != null ? cause.getMessage() : e.getMessage()), e);
} Prevention
- Never hand-edit native plugin XMLs without validating afterwards.
- Validate XML with xmllint or a parser before deploying custom definition files.
- Restore modified XMLs from a clean install.
- Watch getCause() for line/column of the parse failure.
When it happens
Trigger: registerNatives() -> registerPlugins(inputStream) throwing KettleXMLException because the native plugin XML is malformed (bad tag structure, encoding issues, truncated file) or a custom replacement file has invalid content.
Common situations: Hand-editing a plugin XML and introducing a syntax error; a partial/corrupted download or installation of kettle-core; supplying a custom plugin definition file with the wrong schema (missing <plugin> elements).
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Error loading transformation step from XML
- Error loading transformation step from XML
- NullIfMeta.Exception.UnableToReadStepInfoFromXML
- PLUGIN0001
- Unable to read step info from XML node
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/e08ccc539039f291.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/plugins/BasePluginType.java:230
try {
inputStream = getFileInputStreamExternal( xmlFile );
} catch ( Exception e ) {
throw new KettlePluginException( "Unable to load native plugins '" + xmlFile + "'", e );
}
}
if ( inputStream == null ) {
if ( isReturn() ) {
return;
} else {
throw new KettlePluginException( "Unable to find native plugins definition file: " + xmlFile );
}
}
registerPlugins( inputStream );
} catch ( KettleXMLException e ) {
throw new KettlePluginException( "Unable to read the kettle XML config file: " + xmlFile, e );
} finally {
IOUtils.closeQuietly( inputStream );
}
}
@VisibleForTesting
protected String getPropertyExternal( String key, String def ) {
return System.getProperty( key, def );
}
@VisibleForTesting
protected InputStream getResAsStreamExternal( String name ) {
return getClass().getResourceAsStream( name );
}
@VisibleForTesting
protected InputStream getFileInputStreamExternal( String name ) throws FileNotFoundException {
return new FileInputStream( name );View on GitHub (pinned to f3058517a1)