pentaho/pentaho-kettle · error · KettleXMLException

Unable to load step info from XML

Error message

Unable to load step info from XML

What it means

StepsMetricsMeta.readData parses the step's XML node using XMLHandler; any exception while reading the tags is wrapped in a KettleXMLException with message 'Unable to load step info from XML'. It is thrown when the XML representation of the StepsMetrics step in a .ktr file is malformed or unexpected.

Solutions

  1. Open the .ktr in an XML editor/validator and fix the malformed <step> node for the StepsMetrics entry.
  2. Restore the transformation file from version control or a backup.
  3. Re-create the StepsMetrics step in Spoon in a fresh transformation and copy its XML into the broken file.
  4. Confirm the file is not truncated by comparing file size with the original.
  5. Check that the kettle XML is not wrapped in merge-conflict markers (<<<<<<< etc.).

Example fix

// before (broken XML in .ktr)
<fields>
  <stepname>Metrics</stepname>
 <steplinesreadfield>read</steplinesread
// after
<fields>
  <stepname>Metrics</stepname>
  <steplinesreadfield>read</steplinesreadfield>
</fields>
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the .ktr XML before loading
Document doc;
try {
  doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( new File( "trans.ktr" ) );
} catch ( SAXException | IOException e ) {
  throw new IllegalArgumentException( "Transformation XML is malformed", e );
}
// ensure StepsMetrics step node parses
NodeList steps = doc.getElementsByTagName( "step" );

Try / catch

try {
  transMeta = new TransMeta( "trans.ktr" );
} catch ( KettleXMLException e ) {
  if ( e.getMessage().contains( "Unable to load step info from XML" ) ) {
    // restore from backup / fix XML, then retry once
    transMeta = new TransMeta( backupPath );
  } else { throw e; }
}

Prevention

When it happens

Trigger: Loading a .ktr transformation file whose <step> node for StepsMetrics contains malformed XML (unclosed tags, wrong nesting), or whose inner structure cannot be parsed by XMLHandler.getTagValue — e.g. hand-edited XML or a file corrupted in transit.

Common situations: Hand-editing a .ktr file and breaking XML syntax; truncated download/copy of a transformation file; SVN/Git merge conflicts left in the XML; an older/newer plugin writing XML the current parser chokes on; filename extensions changed but content corrupted.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/181c9b19a873553b. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/stepsmetrics/StepsMetricsMeta.java:237

      allocate( nrsteps );

      for ( int i = 0; i < nrsteps; i++ ) {
        Node fnode = XMLHandler.getSubNodeByNr( steps, "step", i );
        stepName[i] = XMLHandler.getTagValue( fnode, "name" );
        stepCopyNr[i] = XMLHandler.getTagValue( fnode, "copyNr" );
        stepRequired[i] = XMLHandler.getTagValue( fnode, "stepRequired" );
      }
      stepnamefield = XMLHandler.getTagValue( stepnode, "stepnamefield" );
      stepidfield = XMLHandler.getTagValue( stepnode, "stepidfield" );
      steplinesinputfield = XMLHandler.getTagValue( stepnode, "steplinesinputfield" );
      steplinesoutputfield = XMLHandler.getTagValue( stepnode, "steplinesoutputfield" );
      steplinesreadfield = XMLHandler.getTagValue( stepnode, "steplinesreadfield" );
      steplinesupdatedfield = XMLHandler.getTagValue( stepnode, "steplinesupdatedfield" );
      steplineswrittentfield = XMLHandler.getTagValue( stepnode, "steplineswrittentfield" );
      steplineserrorsfield = XMLHandler.getTagValue( stepnode, "steplineserrorsfield" );
      stepsecondsfield = XMLHandler.getTagValue( stepnode, "stepsecondsfield" );
    } catch ( Exception e ) {
      throw new KettleXMLException( "Unable to load step info from XML", e );
    }
  }

  public String getXML() {
    StringBuilder retval = new StringBuilder();

    retval.append( "    <steps>" + Const.CR );
    for ( int i = 0; i < stepName.length; i++ ) {
      retval.append( "      <step>" + Const.CR );
      retval.append( "        " + XMLHandler.addTagValue( "name", stepName[i] ) );
      retval.append( "        " + XMLHandler.addTagValue( "copyNr", stepCopyNr[i] ) );
      retval.append( "        " + XMLHandler.addTagValue( "stepRequired", stepRequired[i] ) );
      retval.append( "        </step>" + Const.CR );
    }
    retval.append( "      </steps>" + Const.CR );

    retval.append( "        " + XMLHandler.addTagValue( "stepnamefield", stepnamefield ) );
    retval.append( "        " + XMLHandler.addTagValue( "stepidfield", stepidfield ) );

View on GitHub (pinned to f3058517a1)