pentaho/pentaho-kettle · error · KettleXMLException
Unable to load step info from XML
Error message
Unable to load step info from XML
What it means
StepsMetricsMeta.readData parses the step's XML node using XMLHandler; any exception while reading the tags is wrapped in a KettleXMLException with message 'Unable to load step info from XML'. It is thrown when the XML representation of the StepsMetrics step in a .ktr file is malformed or unexpected.
Solutions
- Open the .ktr in an XML editor/validator and fix the malformed <step> node for the StepsMetrics entry.
- Restore the transformation file from version control or a backup.
- Re-create the StepsMetrics step in Spoon in a fresh transformation and copy its XML into the broken file.
- Confirm the file is not truncated by comparing file size with the original.
- Check that the kettle XML is not wrapped in merge-conflict markers (<<<<<<< etc.).
Example fix
// before (broken XML in .ktr) <fields> <stepname>Metrics</stepname> <steplinesreadfield>read</steplinesread // after <fields> <stepname>Metrics</stepname> <steplinesreadfield>read</steplinesreadfield> </fields>
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the .ktr XML before loading
Document doc;
try {
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( new File( "trans.ktr" ) );
} catch ( SAXException | IOException e ) {
throw new IllegalArgumentException( "Transformation XML is malformed", e );
}
// ensure StepsMetrics step node parses
NodeList steps = doc.getElementsByTagName( "step" ); Try / catch
try {
transMeta = new TransMeta( "trans.ktr" );
} catch ( KettleXMLException e ) {
if ( e.getMessage().contains( "Unable to load step info from XML" ) ) {
// restore from backup / fix XML, then retry once
transMeta = new TransMeta( backupPath );
} else { throw e; }
} Prevention
- Never hand-edit .ktr files without validating the XML afterwards.
- Resolve merge conflicts in transformation files by regenerating in Spoon, not by manual editing.
- Keep transformation files in version control and verify integrity after transfers.
- Open the file in Spoon and save once to normalize the XML after upgrades.
When it happens
Trigger: Loading a .ktr transformation file whose <step> node for StepsMetrics contains malformed XML (unclosed tags, wrong nesting), or whose inner structure cannot be parsed by XMLHandler.getTagValue — e.g. hand-edited XML or a file corrupted in transit.
Common situations: Hand-editing a .ktr file and breaking XML syntax; truncated download/copy of a transformation file; SVN/Git merge conflicts left in the XML; an older/newer plugin writing XML the current parser chokes on; filename extensions changed but content corrupted.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- RulesMeta.Error.LoadFromXML
- RulesMeta.Error.LoadFromXML
- ScriptValuesMetaMod.Exception.UnableToLoadStepInfoFromXML
- AbortMeta.Exception.UnexpectedErrorInReadingStepInfoFromRepo…
- AggregateRowsMeta.Exception.UnableToLoadStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/181c9b19a873553b.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/stepsmetrics/StepsMetricsMeta.java:237
allocate( nrsteps );
for ( int i = 0; i < nrsteps; i++ ) {
Node fnode = XMLHandler.getSubNodeByNr( steps, "step", i );
stepName[i] = XMLHandler.getTagValue( fnode, "name" );
stepCopyNr[i] = XMLHandler.getTagValue( fnode, "copyNr" );
stepRequired[i] = XMLHandler.getTagValue( fnode, "stepRequired" );
}
stepnamefield = XMLHandler.getTagValue( stepnode, "stepnamefield" );
stepidfield = XMLHandler.getTagValue( stepnode, "stepidfield" );
steplinesinputfield = XMLHandler.getTagValue( stepnode, "steplinesinputfield" );
steplinesoutputfield = XMLHandler.getTagValue( stepnode, "steplinesoutputfield" );
steplinesreadfield = XMLHandler.getTagValue( stepnode, "steplinesreadfield" );
steplinesupdatedfield = XMLHandler.getTagValue( stepnode, "steplinesupdatedfield" );
steplineswrittentfield = XMLHandler.getTagValue( stepnode, "steplineswrittentfield" );
steplineserrorsfield = XMLHandler.getTagValue( stepnode, "steplineserrorsfield" );
stepsecondsfield = XMLHandler.getTagValue( stepnode, "stepsecondsfield" );
} catch ( Exception e ) {
throw new KettleXMLException( "Unable to load step info from XML", e );
}
}
public String getXML() {
StringBuilder retval = new StringBuilder();
retval.append( " <steps>" + Const.CR );
for ( int i = 0; i < stepName.length; i++ ) {
retval.append( " <step>" + Const.CR );
retval.append( " " + XMLHandler.addTagValue( "name", stepName[i] ) );
retval.append( " " + XMLHandler.addTagValue( "copyNr", stepCopyNr[i] ) );
retval.append( " " + XMLHandler.addTagValue( "stepRequired", stepRequired[i] ) );
retval.append( " </step>" + Const.CR );
}
retval.append( " </steps>" + Const.CR );
retval.append( " " + XMLHandler.addTagValue( "stepnamefield", stepnamefield ) );
retval.append( " " + XMLHandler.addTagValue( "stepidfield", stepidfield ) );View on GitHub (pinned to f3058517a1)