pentaho/pentaho-kettle · error · KettleException

Transformation type ' ' is an unsupported transformation…

Error message

Transformation type '{0}' is an unsupported transformation type for a mapping

What it means

Mapping (the sub-transformation executor step) only supports Normal, SerialSingleThreaded and SingleThreaded transformation types. When the parent transformation's Mapping step reaches the default branch of its type switch in processRow, the sub-transformation's TransformationType is something the mapping executor cannot drive, so it fails fast with a KettleException including the type description.

Solutions

  1. Open the sub-transformation and set Transformation properties > Transformation type to Normal, then re-run.
  2. Edit the .ktr XML and set the trans_type attribute to Normal (or SingleThreaded/SerialSingleThreaded).
  3. If the ktr comes from a newer PDI version, upgrade the Pentaho Kettle engine to a version that supports that transformation type.
  4. If constructing TransMeta in code, call transMeta.setTransformationType(TransformationType.Normal) before executing the mapping.

Example fix

// before (ktr XML)
<info><trans_type>NormalProcessor</trans_type></info>
// after
<info><trans_type>Normal</trans_type></info>
Defensive patterns

Strategy: validation

Validate before calling

TransformationType t = mappingTransMeta.getTransformationType();
if (t != TransformationType.Normal && t != TransformationType.SingleThreaded
    && t != TransformationType.SerialSingleThreaded) {
  throw new IllegalArgumentException("Unsupported mapping transformation type: " + t);
}

Type guard

boolean isSupportedMappingType(TransMeta tm) {
  TransformationType t = tm == null ? null : tm.getTransformationType();
  return t == TransformationType.Normal
      || t == TransformationType.SingleThreaded
      || t == TransformationType.SerialSingleThreaded;
}

Try / catch

try {
  mapping.processRow();
} catch (KettleException e) {
  if (e.getMessage() != null && e.getMessage().contains("unsupported transformation type")) {
    logError("Fix the sub-transformation's transformation type (use Normal)", e);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Running a mapping whose sub-transformation's TransformationType property resolves to a type not handled by the switch in Mapping.processRow (e.g. a type added in a newer Pentaho version, or a sub-transformation corrupted/misconfigured so getType() returns NormalProcessor-like or unknown types).

Common situations: Opening transformations saved in a newer PDI version in an older engine; manually editing transformation type in the XML/ktr; programmatic construction of TransMeta without setting TransformationType properly; plugins that set custom execution engine types.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/steps/mapping/Mapping.java:255

            List<RowSet> mappingInputRowSets = mappingInputs[0].getInputRowSets();
            log.logDebug( "# of input buffers: " + mappingInputRowSets.size() );
            if ( mappingInputRowSets.size() > 0 ) {
              log.logDebug( "Input buffer 0 size: " + mappingInputRowSets.get( 0 ).size() );
            }
          }

          // Now execute one batch...Basic logging
          //
          boolean result = getData().singleThreadedTransExcecutor.oneIteration();
          if ( !result ) {
            getData().singleThreadedTransExcecutor.dispose();
            setOutputDone();
            return false;
          }
          return true;

        default:
          throw new KettleException( "Transformation type '"
              + getData().mappingTransMeta.getTransformationType().getDescription()
              + "' is an unsupported transformation type for a mapping" );
      }
    } catch ( Throwable t ) {
      // Some unexpected situation occurred.
      // Better to stop the mapping transformation.
      //
      if ( getData().getMappingTrans() != null ) {
        getData().getMappingTrans().stopAll();
      }

      // Forward the exception...
      //
      throw new KettleException( t );
    }
  }

View on GitHub (pinned to f3058517a1)