pentaho/pentaho-kettle · error · KettleXMLException

Unable to find element in the step XML

Error message

Unable to find <mappings> element in the step XML

What it means

When deserializing a Simple Mapping step from a .ktr XML file, SimpleMappingMeta.loadXML looks for the mandatory <mappings> wrapper element that holds the input/output mapping definitions and parameters. If XMLHandler.getSubNode(stepnode, "mappings") returns null, the step XML is malformed or from an unexpected format, so a KettleXMLException is thrown.

Solutions

  1. Inspect the .ktr XML and ensure the Simple Mapping step node contains a <mappings> element with <input>, <output> and <parameters> children; restore it from a backup.
  2. Re-create the Simple Mapping step in Spoon and reconfigure it, then save - this regenerates correct XML.
  3. Use version control history (git show / repository history) to recover the last valid version of the file.
  4. Verify you are opening the file with a compatible Pentaho Data Integration version (serialization format mismatch).

Example fix

// before (broken step XML)
<step><name>Mapping</name><type>SimpleMapping</type></step>
// after
<step><name>Mapping</name><type>SimpleMapping</type>
  <mappings>
    <input>...</input>
    <output>...</output>
    <parameters>...</parameters>
  </mappings>
</step>
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-validate .ktr XML before loading
Document doc = XMLHandler.loadXMLFile(transformationFile);
Node stepsNode = XMLHandler.getSubNode(doc, "transformation", "steps");
for (int i = 0; i < XMLHandler.countNodes(stepsNode, "step"); i++) {
  Node s = XMLHandler.getSubNodeByNr(stepsNode, "step", i);
  if ("SimpleMapping".equals(XMLHandler.getTagValue(s, "type"))
      && XMLHandler.getSubNode(s, "mappings") == null) {
    throw new IllegalStateException("SimpleMapping step XML missing <mappings> element");
  }
}

Try / catch

try {
  meta.loadXML(stepnode, databases, metaStore, variables);
} catch (KettleXMLException e) {
  logError("Corrupt SimpleMapping step XML (missing <mappings>): " + e.getMessage());
  throw new IllegalStateException("Restore the .ktr from backup", e);
}

Prevention

When it happens

Trigger: loadXML() parses a step node whose XML contains no <mappings> child - e.g. a hand-edited or truncated .ktr file, XML produced by an incompatible/older plugin version, or a corrupted repository export.

Common situations: Hand-editing a .ktr and deleting/renaming the <mappings> element; merging XML in git and dropping the block; loading a transformation produced by a different Pentaho/Data Integration version with a changed step serialization; copying a step's XML snippet from another step type.

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/c123ddfcd9548262. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/simplemapping/SimpleMappingMeta.java:136

  public void loadXML( Node stepnode, List<DatabaseMeta> databases, IMetaStore metaStore ) throws KettleXMLException {
    try {
      String method = XMLHandler.getTagValue( stepnode, "specification_method" );
      specificationMethod = ObjectLocationSpecificationMethod.getSpecificationMethodByCode( method );
      String transId = XMLHandler.getTagValue( stepnode, "trans_object_id" );
      transObjectId = Utils.isEmpty( transId ) ? null : new StringObjectId( transId );

      transName = XMLHandler.getTagValue( stepnode, "trans_name" );
      fileName = XMLHandler.getTagValue( stepnode, "filename" );
      directoryPath = XMLHandler.getTagValue( stepnode, "directory_path" );

      // Backward compatibility check for object specification
      //
      checkObjectLocationSpecificationMethod();

      Node mappingsNode = XMLHandler.getSubNode( stepnode, "mappings" );

      if ( mappingsNode == null ) {
        throw new KettleXMLException( "Unable to find <mappings> element in the step XML" );
      }

      // Read all the input mapping definitions...
      //
      Node inputNode = XMLHandler.getSubNode( mappingsNode, "input" );
      Node mappingNode = XMLHandler.getSubNode( inputNode, MappingIODefinition.XML_TAG );
      if ( mappingNode != null ) {
        inputMapping = new MappingIODefinition( mappingNode );
      } else {
        inputMapping = new MappingIODefinition(); // empty
      }
      Node outputNode = XMLHandler.getSubNode( mappingsNode, "output" );
      mappingNode = XMLHandler.getSubNode( outputNode, MappingIODefinition.XML_TAG );
      if ( mappingNode != null ) {
        outputMapping = new MappingIODefinition( mappingNode );
      } else {
        outputMapping = new MappingIODefinition(); // empty
      }

View on GitHub (pinned to f3058517a1)