pentaho/pentaho-kettle · error · KettleXMLException
DenormaliserMeta.Exception.UnableToLoadStepInfoFromXML
DenormaliserMeta.Exception.UnableToLoadStepInfoFromXML
Error message
DenormaliserMeta.Exception.UnableToLoadStepInfoFromXML
What it means
DenormaliserMeta.loadXML reads the step's configuration from the .ktr XML via readData. Any exception while parsing the <denormaliser> block (target field nodes, aggregation types, etc.) is wrapped in a KettleXMLException with this generic message and the original cause preserved.
Solutions
- Inspect the cause chain of the KettleXMLException for the exact parse failure.
- Validate the .ktr XML and confirm the denormaliser step block contains complete target field nodes.
- Recreate the Denormaliser step in Spoon and re-save the transformation to regenerate valid XML.
- Open and re-save the file in the same Pentaho version it will run under.
Example fix
// before (truncated node) <field><field_name>amount</field_name> // after (complete node) <field><field_name>amount</field_name><target_aggregation_type>SUM</target_aggregation_type>...</field>
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate XML well-formedness before loading DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(ktrPath));
Try / catch
try { denormMeta.loadXML(node, databases, metaStore); } catch (KettleXMLException e) {
log.error("Denormaliser XML load failed: {}", e.getCause(), e);
} Prevention
- Edit transformations only through Spoon, never by hand-editing XML.
- Version-control .ktr files to detect corruption quickly.
- Re-save transformations when migrating between Pentaho versions.
- Check the cause chain to locate the malformed node.
When it happens
Trigger: loadXML -> readData hits an Exception while reading denormaliserTargetField nodes via XMLHandler.getTagValue (missing nodes, malformed XML, incompatible attributes).
Common situations: Hand-edited or truncated .ktr file; XML produced by a different Pentaho version with a changed schema; corrupted save; copy-pasted step XML missing required child nodes.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- DeleteMeta.Exception.UnableToReadStepInfoFromXML
- 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/64279ad483d5e529.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/denormaliser/DenormaliserMeta.java:246
denormaliserTargetField[i].setTargetName( XMLHandler.getTagValue( fnode, "target_name" ) );
denormaliserTargetField[i].setTargetType( XMLHandler.getTagValue( fnode, "target_type" ) );
denormaliserTargetField[i].setTargetFormat( XMLHandler.getTagValue( fnode, "target_format" ) );
denormaliserTargetField[i].setTargetLength( Const.toInt(
XMLHandler.getTagValue( fnode, "target_length" ), -1 ) );
denormaliserTargetField[i].setTargetPrecision( Const.toInt( XMLHandler.getTagValue(
fnode, "target_precision" ), -1 ) );
denormaliserTargetField[i]
.setTargetDecimalSymbol( XMLHandler.getTagValue( fnode, "target_decimal_symbol" ) );
denormaliserTargetField[i].setTargetGroupingSymbol( XMLHandler.getTagValue(
fnode, "target_grouping_symbol" ) );
denormaliserTargetField[i].setTargetCurrencySymbol( XMLHandler.getTagValue(
fnode, "target_currency_symbol" ) );
denormaliserTargetField[i].setTargetNullString( XMLHandler.getTagValue( fnode, "target_null_string" ) );
denormaliserTargetField[i].setTargetAggregationType( XMLHandler.getTagValue(
fnode, "target_aggregation_type" ) );
}
} catch ( Exception e ) {
throw new KettleXMLException( BaseMessages.getString(
PKG, "DenormaliserMeta.Exception.UnableToLoadStepInfoFromXML" ), e );
}
}
public String getXML() {
StringBuilder retval = new StringBuilder();
retval.append( " " + XMLHandler.addTagValue( "key_field", keyField ) );
retval.append( " <group>" + Const.CR );
for ( int i = 0; i < groupField.length; i++ ) {
retval.append( " <field>" + Const.CR );
retval.append( " " + XMLHandler.addTagValue( "name", groupField[i] ) );
retval.append( " </field>" + Const.CR );
}
retval.append( " </group>" + Const.CR );
retval.append( " <fields>" + Const.CR );View on GitHub (pinned to f3058517a1)