pentaho/pentaho-kettle · error · KettleXMLException
ChangeFileEncodingMeta.Exception.UnableToReadStepInfo
ChangeFileEncodingMeta.Exception.UnableToReadStepInfo
Error message
ChangeFileEncodingMeta.Exception.UnableToReadStepInfo
What it means
ChangeFileEncodingMeta.readData() wraps XML parsing of the step's serialized configuration in a try/catch and rethrows as KettleXMLException with this message when loading the step from a transformation .ktr file. It indicates the step XML node is malformed or contains unexpected content.
Solutions
- Open the .ktr in Spoon and re-create the Change File Encoding step.
- Compare the step's XML block against a freshly saved step and repair missing tags (sourcename, targetname, sourceencoding, targetencoding, etc.).
- Restore the transformation file from backup/version control.
- Ensure the plugin version matches the Pentaho version that wrote the file.
Example fix
<!-- before: missing tags --> <step><name>Change file encoding</name><type>ChangeFileEncoding</type></step> <!-- after: restore required fields --> <step><name>Change file encoding</name><type>ChangeFileEncoding</type> <sourceencoding>UTF-8</sourceencoding><targetencoding>ISO-8859-1</targetencoding></step>
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the .ktr is well-formed XML before loading import javax.xml.parsers.DocumentBuilderFactory; DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( new File( "t.ktr" ) ); // throws on malformed XML
Try / catch
try {
TransMeta tm = new TransMeta( "t.ktr" );
} catch ( KettleXMLException e ) {
if ( e.getMessage().contains( "UnableToReadStepInfo" ) ) {
log.error( "Corrupt ChangeFileEncoding step XML: {}", e.getCause(), e );
} else { throw e; }
} Prevention
- Do not hand-edit .ktr files; edit via Spoon only.
- Keep transformation files in version control so corruption can be reverted.
- Use the same Pentaho version to write and read transformation files.
When it happens
Trigger: In readData (called from loadXML): XMLHandler.getTagValue calls on the stepnode throw — e.g. stepnode is null, the XML is corrupted, or a hand-edited .ktr broke the <fields> structure of this step.
Common situations: Hand-editing or partial copy/paste of a .ktr file; transformation produced by an older Pentaho version with incompatible step XML; file truncated on disk or in version control.
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
- AddSequenceMeta.Exception.ErrorLoadingStepInfo
- AnalyticQueryMeta.Exception.UnableToLoadStepInfoFromXML
- CombinationLookupMeta.Exception.UnableToLoadStepInfo
- Error loading transformation step from XML
- Error loading transformation step from XML
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/87e6a0bf4ef14ff6.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/core/impl/src/main/java/org/pentaho/di/trans/steps/changefileencoding/ChangeFileEncodingMeta.java:192
retval.append( " " ).append( XMLHandler.addTagValue( "addsourceresultfilenames", addsourceresultfilenames ) );
retval.append( " " ).append( XMLHandler.addTagValue( "addtargetresultfilenames", addtargetresultfilenames ) );
retval.append( " " ).append( XMLHandler.addTagValue( "createparentfolder", createparentfolder ) );
return retval.toString();
}
private void readData( Node stepnode, List<DatabaseMeta> databases ) throws KettleXMLException {
try {
filenamefield = XMLHandler.getTagValue( stepnode, "filenamefield" );
targetfilenamefield = XMLHandler.getTagValue( stepnode, "targetfilenamefield" );
sourceencoding = XMLHandler.getTagValue( stepnode, "sourceencoding" );
targetencoding = XMLHandler.getTagValue( stepnode, "targetencoding" );
addsourceresultfilenames = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "addsourceresultfilenames" ) );
addtargetresultfilenames = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "addtargetresultfilenames" ) );
createparentfolder = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "createparentfolder" ) );
} catch ( Exception e ) {
throw new KettleXMLException(
BaseMessages.getString( PKG, "ChangeFileEncodingMeta.Exception.UnableToReadStepInfo" ), e );
}
}
public void readRep( Repository rep, IMetaStore metaStore, ObjectId id_step, List<DatabaseMeta> databases )
throws KettleException {
try {
filenamefield = rep.getStepAttributeString( id_step, "filenamefield" );
targetfilenamefield = rep.getStepAttributeString( id_step, "targetfilenamefield" );
sourceencoding = rep.getStepAttributeString( id_step, "sourceencoding" );
targetencoding = rep.getStepAttributeString( id_step, "targetencoding" );
addsourceresultfilenames = rep.getStepAttributeBoolean( id_step, "addsourceresultfilenames" );
addtargetresultfilenames = rep.getStepAttributeBoolean( id_step, "addtargetresultfilenames" );
createparentfolder = rep.getStepAttributeBoolean( id_step, "createparentfolder" );
} catch ( Exception e ) {
throw new KettleException(View on GitHub (pinned to f3058517a1)