pentaho/pentaho-kettle · error · KettleXMLException
StepMeta.Exception.UnableToLoadStepInfo
StepMeta.Exception.UnableToLoadStepInfo
Error message
StepMeta.Exception.UnableToLoadStepInfo
What it means
KettleXMLException thrown by StepMeta.loadXML when any unexpected exception occurs while parsing a <step> element from a transformation XML. It means the step's metadata could not be loaded — either the XML is malformed/missing required sub-nodes, or the step's plugin could not be instantiated. The original exception is chained as the cause.
Solutions
- Check the chained cause exception ('Caused by') to find the real failure — usually a missing plugin class or bad XML attribute
- Install the missing step plugin JAR into the plugins/ directory (verify plugin id in the XML <type> matches)
- Open the .ktr in the matching or newer Pentaho/Spoon version the file was created with
- Validate/repair the XML: check numeric fields like copies, slavenumber, and required sub-nodes
Example fix
// before: transformation references a plugin not installed <step><type>MyCustomStep</type>...</step> // after: install my-custom-step plugin jar into plugins/my-custom-step/ <step><type>MyCustomStep</type>...</step>
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the .ktr before loading
File xmlFile = new File("trans.ktr");
Document doc = XMLHandler.loadXMLFile(xmlFile);
Node[] stepNodes = XMLHandler.getNodes(doc, KettleAttributeConstants.STRING_TRANSFORMATION + "_steps");
// For each step node, check <type> against installed plugins:
// PluginRegistry.getInstance().getPlugin(StepPluginType.class, stepType) != null Type guard
boolean stepPluginAvailable(String type) {
return PluginRegistry.getInstance().getPlugin(StepPluginType.class, type) != null;
} Try / catch
try {
transMeta.loadXML(...);
} catch (KettleXMLException e) {
log.error("Step load failed: " + e.getMessage(), e); // inspect getCause()
// check e.getCause() instanceof KettlePluginLoaderException -> missing plugin
throw new MissingPluginException("Install plugin: " + extractStepType(e), e);
} Prevention
- Keep step plugins in sync with transformation files (same Pentaho version everywhere)
- Before loading, scan step <type> values against PluginRegistry
- Never hand-edit .ktr XML; use Spoon
- Pin transformation files to the environment's Kettle version in version control
When it happens
Trigger: StepMeta.loadXML() parses a step node and throws inside the try block: malformed XML fields (e.g. non-numeric distribution/copies attributes), missing plugin id, or failure while loading the step plugin that RemoteStep/partitioning setup depends on. Explicitly rethrown if a KettlePluginLoaderException occurs while loading the step's plugin class.
Common situations: Transformation .ktr files from a newer Pentaho version opened in an older Spoon; missing/failed step plugins (plugin JAR not in plugins/ directory); hand-edited XML with invalid values; corrupted repository-stored transformations.
Related errors
- AbortMeta.Exception.UnexpectedErrorInReadingStepInfoFromRepo…
- AggregateRowsMeta.Exception.UnableToLoadStepInfo
- AppendMeta.Exception.UnableToLoadStepInfo
- LucidDBStreamingLoaderMeta.Exception.UnableToReadStepInfoFromXML
- RulesMeta.Error.LoadFromXML
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/aaf3aee9718cb26f.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/step/StepMeta.java:398
// The remote input and output steps...
Node remotestepsNode = XMLHandler.getSubNode( stepnode, "remotesteps" );
Node inputNode = XMLHandler.getSubNode( remotestepsNode, "input" );
int nrInput = XMLHandler.countNodes( inputNode, RemoteStep.XML_TAG );
for ( int i = 0; i < nrInput; i++ ) {
remoteInputSteps.add( new RemoteStep( XMLHandler.getSubNodeByNr( inputNode, RemoteStep.XML_TAG, i ) ) );
}
Node outputNode = XMLHandler.getSubNode( remotestepsNode, "output" );
int nrOutput = XMLHandler.countNodes( outputNode, RemoteStep.XML_TAG );
for ( int i = 0; i < nrOutput; i++ ) {
remoteOutputSteps.add( new RemoteStep( XMLHandler.getSubNodeByNr( outputNode, RemoteStep.XML_TAG, i ) ) );
}
}
} catch ( KettlePluginLoaderException e ) {
throw e;
} catch ( Exception e ) {
throw new KettleXMLException( BaseMessages.getString( PKG, "StepMeta.Exception.UnableToLoadStepInfo" ) + e
.toString(), e );
}
}
/**
* Just in case we missed a v4 plugin using deprecated methods.
*
* @param stepMetaInterface2
* @param stepnode
* @param databases
* @throws KettleXMLException
*/
@SuppressWarnings( "deprecation" )
private void loadXmlCompatibleStepMeta( StepMetaInterface stepMetaInterface2, Node stepnode,
List<DatabaseMeta> databases ) throws KettleXMLException {
stepMetaInterface.loadXML( stepnode, databases, new HashMap<String, Counter>() );
}
View on GitHub (pinned to f3058517a1)