pentaho/pentaho-kettle · error · KettleXMLException
Unable to load step info from XML
Error message
Unable to load step info from XML
What it means
MondrianInputMeta.readData parses the step's XML node (connection, sql, catalog, role, variables_active tags) when a transformation is loaded from a .ktr file. Any exception during deserialization is wrapped in a KettleXMLException with this fixed message. It signals a malformed or incompatible step XML block in the transformation file.
Solutions
- Open the .ktr in a text editor and verify the step XML node contains connection, sql, catalog, role and variables_active tags with valid values
- Confirm the referenced connection name exists in the transformation's <connection> definitions
- Recreate or re-save the Mondrian input step in Spoon to regenerate well-formed XML
- Check PDI version compatibility between the file and the running engine
Defensive patterns
Strategy: validation
Validate before calling
// Validate a .ktr before loading
String xml = new String(Files.readAllBytes(Paths.get("trans.ktr")), StandardCharsets.UTF_8);
Document doc = XMLHandler.loadXMLString(xml);
Node step = XMLHandler.getSubNode(doc, "step");
for (String tag : new String[]{"connection", "sql", "catalog", "role", "variables_active"}) {
if (XMLHandler.getTagValue(step, tag) == null) {
throw new IllegalArgumentException("Missing tag in Mondrian step XML: " + tag);
}
} Type guard
null
Try / catch
try {
transMeta = new TransMeta("trans.ktr", metaStore);
} catch (KettleXMLException e) {
if (e.getMessage().contains("Unable to load step info from XML")) {
logError("Corrupt .ktr Mondrian step block; check XML tags", e);
}
} Prevention
- Never hand-edit .ktr XML; re-save steps from Spoon
- Keep transformations in version control to restore corrupted files
- Match PDI versions between authoring and execution environments
- Validate XML with a linter after automated .ktr generation
When it happens
Trigger: loadXML is called on a .ktr whose Mondrian input step node is missing expected child tags or contains values that make XMLHandler/DatabaseMeta.findDatabase throw (e.g. null stepnode, corrupt connection reference).
Common situations: Hand-edited or partially migrated .ktr files; transformations authored in a different PDI version with changed XML layout; truncated or corrupted exports.
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
- Unable to load step info from XML
- AbortMeta.Exception.UnexpectedErrorInReadingStepInfoFromRepo…
- CloneRowMeta.Exception.UnableToReadStepInfo
- ColumnExistsMeta.Exception.UnableToReadStepInfo
- CreditCardValidatorMeta.Exception.UnableToReadStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/a63236dfdec0722e.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/mondrianinput/impl/src/main/java/org/pentaho/di/trans/steps/mondrianinput/MondrianInputMeta.java:136
public void loadXML( Node stepnode, List<DatabaseMeta> databases, IMetaStore metaStore ) throws KettleXMLException {
readData( stepnode, databases );
}
public Object clone() {
MondrianInputMeta retval = (MondrianInputMeta) super.clone();
return retval;
}
private void readData( Node stepnode, List<DatabaseMeta> databases ) throws KettleXMLException {
try {
databaseMeta = DatabaseMeta.findDatabase( databases, XMLHandler.getTagValue( stepnode, "connection" ) );
sql = XMLHandler.getTagValue( stepnode, "sql" );
catalog = XMLHandler.getTagValue( stepnode, "catalog" );
role = XMLHandler.getTagValue( stepnode, "role" );
variableReplacementActive = "Y".equals( XMLHandler.getTagValue( stepnode, "variables_active" ) );
} catch ( Exception e ) {
throw new KettleXMLException( "Unable to load step info from XML", e );
}
}
public void setDefault() {
databaseMeta = null;
sql =
"select\n"
+ " {([Gender].[F], [Measures].[Unit Sales]),\n" + " ([Gender].[M], [Measures].[Store Sales]),\n"
+ " ([Gender].[F], [Measures].[Unit Sales])} on columns,\n"
+ " CrossJoin([Marital Status].Members,\n" + " [Product].Children) on rows\n"
+ "from [Sales]";
variableReplacementActive = false;
}
@Override
public void getFields( Bowl bowl, RowMetaInterface row, String origin, RowMetaInterface[] info, StepMeta nextStep,
VariableSpace space, Repository repository, IMetaStore metaStore ) throws KettleStepException {
if ( databaseMeta == null ) {View on GitHub (pinned to f3058517a1)