pentaho/pentaho-kettle · error · KettleXMLException
Unable to load step info from XML
Error message
Unable to load step info from XML
What it means
KettleXMLException thrown by AccessInputMeta.loadXML when any exception occurs while reading the step's configuration from its XML node (file lists, field definitions, dynamic-field names, etc.). The generic message 'Unable to load step info from XML' wraps the underlying parse error in its cause.
Solutions
- Inspect the cause exception in the stack trace to find which tag/attribute failed.
- Open the transformation in Spoon, delete and re-create the Access Input step to regenerate valid XML.
- Compare the step's XML block in the .ktr against a working Access Input step and restore missing/malformed tags.
- Align PDI versions — if the .ktr comes from a newer release, open it with a matching or newer Spoon version.
Example fix
// before (missing <field> children breaks allocation) <fields> </fields> // after <fields> <field><name>id</name><column>ID</column><type>Integer</type></field> </fields>
Defensive patterns
Strategy: try-catch
Try / catch
try { stepMeta.loadXML( stepnode, databases, metaStore ); } catch ( KettleXMLException e ) { logError( "Access Input XML invalid: " + e.getCause(), e ); /* re-create the step in Spoon */ } Prevention
- Never hand-edit the Access Input <step> block in .ktr files
- Keep transformations within one PDI version family
- Diff .ktr files in version control to catch dropped tags
- Re-create the step rather than patching XML when it fails to load
When it happens
Trigger: loadXML(Node stepnode, ...) catching Exception: stepnode is missing expected tags (filename, field, filename_Field, lastModificationTimeFieldName, etc.), attributes have unexpected structure, or the .ktr was produced by an incompatible PDI version.
Common situations: Hand-editing .ktr files and dropping a required tag; merging transformations by copy/paste with corrupted node content; opening a transformation saved by a newer PDI release in an older one; XML encoding issues after round-tripping through other tools.
Related errors
- AccessInputMeta.Exception.ErrorReadingRepository
- ConcatFieldsMeta.CheckResult.TargetFieldNameMissing
- CubeInputMeta.Exception.UnableToLoadStepInfo
- FileLockedMeta.Exception.UnableToReadStepInfo
- FilterRowsMeta.Exception..UnableToLoadStepInfoFromXML
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/9446855ed10386d5.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/ms-access/impl/src/main/java/org/pentaho/di/trans/steps/accessinput/AccessInputMeta.java:783
inputFields[i].setFormat( XMLHandler.getTagValue( fnode, "format" ) );
inputFields[i].setCurrencySymbol( XMLHandler.getTagValue( fnode, "currency" ) );
inputFields[i].setDecimalSymbol( XMLHandler.getTagValue( fnode, "decimal" ) );
inputFields[i].setGroupSymbol( XMLHandler.getTagValue( fnode, "group" ) );
}
// Is there a limit on the number of rows we process?
rowLimit = Const.toLong( XMLHandler.getTagValue( stepnode, "limit" ), 0L );
shortFileFieldName = XMLHandler.getTagValue( stepnode, "shortFileFieldName" );
pathFieldName = XMLHandler.getTagValue( stepnode, "pathFieldName" );
hiddenFieldName = XMLHandler.getTagValue( stepnode, "hiddenFieldName" );
lastModificationTimeFieldName = XMLHandler.getTagValue( stepnode, "lastModificationTimeFieldName" );
uriNameFieldName = XMLHandler.getTagValue( stepnode, "uriNameFieldName" );
rootUriNameFieldName = XMLHandler.getTagValue( stepnode, "rootUriNameFieldName" );
extensionFieldName = XMLHandler.getTagValue( stepnode, "extensionFieldName" );
sizeFieldName = XMLHandler.getTagValue( stepnode, "sizeFieldName" );
} catch ( Exception e ) {
throw new KettleXMLException( "Unable to load step info from XML", e );
}
}
public void allocate( int nrfiles, int nrfields ) {
allocateFiles( nrfiles );
allocateFields( nrfields );
}
public void allocateFiles( int nrfiles ) {
fileName = new String[nrfiles];
fileMask = new String[nrfiles];
excludeFileMask = new String[nrfiles];
fileRequired = new String[nrfiles];
includeSubFolders = new String[nrfiles];
}
public void allocateFields( int nrfields ) {
inputFields = new AccessInputField[nrfields];View on GitHub (pinned to f3058517a1)