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

  1. Open the .ktr in Spoon and re-create the Change File Encoding step.
  2. Compare the step's XML block against a freshly saved step and repair missing tags (sourcename, targetname, sourceencoding, targetencoding, etc.).
  3. Restore the transformation file from backup/version control.
  4. 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

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


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)