pentaho/pentaho-kettle · error · KettleXMLException

TransMeta.Exception.ErrorReadingTransformation

Error message

TransMeta.Exception.ErrorReadingTransformation

What it means

Inside loadXML(transnode, ...), any KettleXMLException raised while reading the transformation node's sub-elements (info node, attributes, logging tables, etc.) is re-wrapped as KettleXMLException with TransMeta.Exception.ErrorReadingTransformation, chaining the original cause. It signals a structural problem in the transformation XML content itself.

Solutions

  1. Inspect the chained cause (xe) to find the exact XML element that failed
  2. Re-save the transformation in Spoon to normalize it to your Kettle version's schema
  3. Align the PDI client/plugin versions used to create and to load the .ktr

Example fix

// before
} catch (KettleXMLException xe) {
  throw xe; // unclear where it failed
}
// after
} catch (KettleXMLException xe) {
  throw new KettleXMLException(BaseMessages.getString(PKG, "TransMeta.Exception.ErrorReadingTransformation"), xe);
} // then log/print xe.getCause() to locate the offending node
Defensive patterns

Strategy: try-catch

Try / catch

try {
  transMeta.loadXML(transnode, fname, metaStore, rep, true, variableSpace, null);
} catch (KettleXMLException e) {
  Throwable cause = e.getCause();
  logger.error("Error reading transformation {}: {}", fname, cause == null ? e.getMessage() : cause.getMessage(), e);
  throw e;
}

Prevention

When it happens

Trigger: new TransMeta(fname) or loadXML() on a .ktr whose inner elements are malformed for Kettle's expected schema: missing <info> node, invalid attributes XML, bad logging-table definitions, unexpected nested tags.

Common situations: Hand-edited .ktr files; transformations saved by a newer/older Pentaho version with changed schema; truncated downloads; third-party generators writing non-conformant XML.

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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/TransMeta.java:3730

        // Is this a slave transformation?
        //
        slaveTransformation = "Y".equalsIgnoreCase( XMLHandler.getTagValue( transnode, "slave_transformation" ) );
        if ( log.isDebug() ) {
          log.logDebug( BaseMessages.getString( PKG, "TransMeta.Log.NumberOfStepsReaded" ) + nrSteps() );
          log.logDebug( BaseMessages.getString( PKG, "TransMeta.Log.NumberOfHopsReaded" ) + nrTransHops() );
        }
        sortSteps();

        // Load the attribute groups map
        //
        attributesMap = AttributesUtil.loadAttributes( XMLHandler.getSubNode( transnode, AttributesUtil.XML_TAG ) );

        keyForSessionKey = XMLHandler.stringToBinary( XMLHandler.getTagValue( infonode, "key_for_session_key" ) );
        isKeyPrivate = "Y".equals( XMLHandler.getTagValue( infonode, "is_key_private" ) );

      } catch ( KettleXMLException xe ) {
        throw new KettleXMLException( BaseMessages.getString( PKG, "TransMeta.Exception.ErrorReadingTransformation" ),
            xe );
      } catch ( KettleException e ) {
        throw new KettleXMLException( e );
      } finally {
        initializeVariablesFrom( null );
        if ( setInternalVariables ) {
          setInternalKettleVariables();
        }

        ExtensionPointHandler.callExtensionPoint( log, KettleExtensionPoint.TransformationMetaLoaded.id, this );
      }
    } catch ( Exception e ) {
      // See if we have missing plugins to report, those take precedence!
      //
      if ( !missingPluginsException.getMissingPluginDetailsList().isEmpty() ) {
        throw missingPluginsException;
      } else {
        throw new KettleXMLException( BaseMessages.getString( PKG, "TransMeta.Exception.ErrorReadingTransformation" ),

View on GitHub (pinned to f3058517a1)