pentaho/pentaho-kettle · error · KettleXMLException

Unable to load step info from XML

Error message

Unable to load step info from XML

What it means

XMLInputStreamMeta.loadXML() parses step configuration from a transformation XML node using XMLHandler.getTagValue(). Any exception while reading those attributes is wrapped in a KettleXMLException with the message 'Unable to load step info from XML', with the underlying cause chained. This is a serialization/deserialization boundary error: the step definition stored in a .ktr file is unreadable or invalid.

Solutions

  1. Open the .ktr in a text editor and validate the XML well-formedness (e.g. xmllint --noout file.ktr); fix syntax errors.
  2. Check the chained cause exception (e.getCause()) to identify which element failed to parse.
  3. Recreate the XMLInputStream step in Spoon and re-enter its settings instead of editing XML manually.
  4. Verify the transformation was exported by a compatible PDI version; re-export or upgrade the PDI version.
  5. Restore the .ktr from source control or a backup if the file is corrupted.

Example fix

// before: hand-edited XML with a missing closing tag inside the step node
<step name="XML Input" type="XMLInputStream">
  <encoding>UTF-8
</step>
// after: well-formed step node
<step name="XML Input" type="XMLInputStream">
  <encoding>UTF-8</encoding>
</step>
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the .ktr is well-formed before loading
Document doc = XMLHandler.loadXMLFile(new File("trans.ktr"));
if (doc == null) throw new IllegalArgumentException("Malformed transformation XML");

Type guard

boolean isReadableStepNode(Node stepnode) {
  return stepnode != null && stepnode.getNodeType() == Node.ELEMENT_NODE
      && "step".equals(stepnode.getNodeName());
}

Try / catch

try {
  transMeta.loadXML(...);
} catch (KettleXMLException e) {
  log.error("Step XML unreadable: {}", e.getCause(), e);
  // fall back to backup .ktr or prompt user to re-create the step
}

Prevention

When it happens

Trigger: Opening/validating a .ktr transformation whose XMLInputStream step XML node contains malformed XML, an unexpected node structure, or whose attribute parsing throws (e.g. XMLHandler.getTagValue fails on a malformed stepnode subtree). Also thrown when a transformation was written by an incompatible PDI version with an unreadable step entry.

Common situations: Hand-edited .ktr files with broken XML; transformations from newer PDI versions opened in older ones; corrupted repository exports; copying step XML between transformations with mismatched structure; encoding issues in the file.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at plugins/xml/core/src/main/java/org/pentaho/di/trans/steps/xmlinputstream/XMLInputStreamMeta.java:301

          "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "includeXmlElementLevelField" ) );
      xmlElementLevelField =
          Const.NVL( XMLHandler.getTagValue( stepnode, "xmlElementLevelField" ), xmlElementLevelField );

      includeXmlPathField = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "includeXmlPathField" ) );
      xmlPathField = Const.NVL( XMLHandler.getTagValue( stepnode, "xmlPathField" ), xmlPathField );

      includeXmlParentPathField =
          "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "includeXmlParentPathField" ) );
      xmlParentPathField = Const.NVL( XMLHandler.getTagValue( stepnode, "xmlParentPathField" ), xmlParentPathField );

      includeXmlDataNameField = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "includeXmlDataNameField" ) );
      xmlDataNameField = Const.NVL( XMLHandler.getTagValue( stepnode, "xmlDataNameField" ), xmlDataNameField );

      includeXmlDataValueField = "Y".equalsIgnoreCase( XMLHandler.getTagValue( stepnode, "includeXmlDataValueField" ) );
      xmlDataValueField = Const.NVL( XMLHandler.getTagValue( stepnode, "xmlDataValueField" ), xmlDataValueField );

    } catch ( Exception e ) {
      throw new KettleXMLException( "Unable to load step info from XML", e );
    }
  }

  @Override
  public Object clone() {
    XMLInputStreamMeta retval = (XMLInputStreamMeta) super.clone();
    // TODO check

    return retval;
  }

  @Override
  public String getXML() {
    StringBuffer retval = new StringBuffer();
    retval.append( "    " + XMLHandler.addTagValue( "sourceFromInput", sourceFromInput ) );
    retval.append( "    " + XMLHandler.addTagValue( "sourceFieldName", sourceFieldName ) );
    retval.append( "    " + XMLHandler.addTagValue( "filename", filename ) );
    retval.append( "    " + XMLHandler.addTagValue( "addResultFile", addResultFile ) );

View on GitHub (pinned to f3058517a1)