pentaho/pentaho-kettle · error · KettleXMLException
YamlInputMeta.Exception.ErrorLoadingXML
Error message
YamlInputMeta.Exception.ErrorLoadingXML
What it means
YamlInputMeta.readData wraps XML deserialization of the step's settings; any exception while reading tags from the step XML node is rethrown as a KettleXMLException with this message, including the underlying exception's toString. It protects the loader from partially corrupt step metadata.
Solutions
- Read the nested exception in the message to identify which tag/value failed to parse.
- Open the .ktr in a text editor and fix or remove the malformed tag for this step (e.g. non-numeric <limit>).
- Recreate the YAML Input step in Spoon and re-enter its settings.
- Align PDI versions between the environment that wrote and the one reading the transformation.
Example fix
// before: corrupt XML <limit>abc</limit> // after: valid numeric value <limit>0</limit>
Defensive patterns
Strategy: try-catch
Validate before calling
// validate XML before handing it to Kettle
try { Document d = XMLHandler.loadXMLString(xml); if (d == null) throw new IllegalArgumentException("null step node"); }
catch (KettleXMLException e) { throw new IllegalArgumentException("malformed step XML", e); } Try / catch
try { meta.loadXML(stepNode, databases, metaStore, transMeta, null); }
catch (KettleXMLException e) {
log.error("Corrupt YAML Input step XML: " + e.getMessage(), e);
meta = new YamlInputMeta(); // fall back to defaults and reconfigure
} Prevention
- Never hand-edit .ktr files; edit in Spoon.
- Keep writer and reader PDI versions aligned.
- Keep transformations in version control to restore known-good XML.
When it happens
Trigger: loadXML -> readData: any XMLHandler.getTagValue call or conversion (e.g. Const.toLong on 'limit', boolean parsing of 'IsInFields') throws because the XML fragment is malformed or an unexpected value is present.
Common situations: Hand-edited .ktr files, transformations written by a different PDI version with an incompatible schema, truncated/corrupt repository export, copy-paste of XML between transformations with mismatched tags.
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
- SynchronizeAfterMergeMeta.Exception.UnableToReadStepInfoFrom…
- CubeInputMeta.Exception.UnableToLoadStepInfo
- FuzzyMatchMeta.Exception.UnableToLoadStepInfoFromXML
- GetPreviousRowFieldMeta.Exception.UnableToReadStepInfoFromXM…
- GetXMLDataMeta.Exception.ErrorLoadingXML (localized message…
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/6fbcfb1883865a01.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/yaml-input/impl/src/main/java/org/pentaho/di/trans/steps/yamlinput/YamlInputMeta.java:513
fileName[i] = XMLHandler.getNodeValue( filenamenode );
fileMask[i] = XMLHandler.getNodeValue( filemasknode );
fileRequired[i] = XMLHandler.getNodeValue( fileRequirednode );
includeSubFolders[i] = XMLHandler.getNodeValue( includeSubFoldersnode );
}
for ( int i = 0; i < nrFields; i++ ) {
Node fnode = XMLHandler.getSubNodeByNr( fields, "field", i );
YamlInputField field = new YamlInputField( fnode );
inputFields[i] = field;
}
// Is there a limit on the number of rows we process?
rowLimit = Const.toLong( XMLHandler.getTagValue( stepnode, "limit" ), 0L );
inFields = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "IsInFields" ) );
IsAFile = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "IsAFile" ) );
yamlField = XMLHandler.getTagValue( stepnode, "YamlField" );
} catch ( Exception e ) {
throw new KettleXMLException( BaseMessages.getString( PKG, "YamlInputMeta.Exception.ErrorLoadingXML", e
.toString() ) );
}
}
public void allocate( int nrfiles, int nrfields ) {
fileName = new String[nrfiles];
fileMask = new String[nrfiles];
fileRequired = new String[nrfiles];
includeSubFolders = new String[nrfiles];
inputFields = new YamlInputField[nrfields];
}
@Override
public void setDefault() {
IsIgnoreEmptyFile = false;
doNotFailIfNoFile = true;
includeFilename = false;
filenameField = "";View on GitHub (pinned to f3058517a1)