pentaho/pentaho-kettle · error · KettleException

Unsupported situation detected where a remote output step…

Error message

Unsupported situation detected where a remote output step is expecting data to end up in a particular Mapping Output step of a sub-transformation.  To solve it, insert a dummy step after the mapping.

What it means

In Mapping.processRow, remote output steps are added to mappingOutputs[0].getRemoteOutputSteps(). When the sub-transformation has multiple Mapping Output steps, the remote output step cannot be assigned unambiguously, so this KettleException is thrown. It enforces a single destination for remotely consumed output in clustered execution.

Solutions

  1. Insert a Dummy step after the Mapping step to disambiguate output wiring.
  2. Reduce the sub-transformation to a single Mapping Output step.
  3. Adjust cluster schema / step copy settings so the output hop is not remote to multiple Mapping Outputs.
  4. Redesign with explicit 'Mapping (sub-transformation)' output specification if multiple outputs are required.

Example fix

// before (clustered)
Mapping(sub.ktr) =====> RemoteOutput  // sub.ktr: 2x MappingOutput
// after
Mapping(sub.ktr) =====> Dummy =====> RemoteOutput  // or single MappingOutput
Defensive patterns

Strategy: validation

Validate before calling

// Before clustered execution, assert single Mapping Output in the sub-transformation:
long mappingOutputs = subTransMeta.getSteps().stream()
  .filter(s -> s.getStepMeta() instanceof MappingOutputMeta).count();
if (mappingOutputs > 1) throw new IllegalStateException("Remote execution requires exactly one Mapping Output");

Try / catch

try {
  trans.execute(new String[0]); // clustered run
} catch (KettleException e) {
  if (e.getMessage().contains("remote output step")) {
    log.error("Remote output cannot target multiple Mapping Outputs: add Dummy step or reduce to one", e);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Clustered/remote execution where the Mapping step's sub-transformation contains multiple Mapping Output steps, and a remote output step expects data from one specific Mapping Output — during remote-output wiring in processRow.

Common situations: Deploying a locally developed transformation (sub-transf with several Mapping Outputs) onto a cluster; cluster schema changes making previously local hops remote.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

            // over remotely to this mapping.
            // However, the data needs to end up at a Mapping Output step of the
            // sub-transformation, not in this step.
            // We can move over the remote steps to the Mapping Output step as long
            // as the threads haven't started yet.
            //
            for ( RemoteStep remoteStep : getRemoteOutputSteps() ) {
              // Pass this rowset down to a mapping output step in the
              // sub-transformation...
              //
              if ( mappingOutputs.length == 1 ) {
                // Simple case: only one output mapping. Move the remote step over
                //
                mappingOutputs[0].getRemoteOutputSteps().add( remoteStep );
              } else {
                // TODO: figure out where this remote step needs to go and where
                // it comes from.
                //
                throw new KettleException(
                    "Unsupported situation detected where a remote output step is expecting data "
                        + "to end up in a particular Mapping Output step of a sub-transformation.  "
                        + "To solve it, insert a dummy step after the mapping." );
              }
            }
            getRemoteOutputSteps().clear();
          }

          // Start the mapping/sub-transformation threads
          //
          getData().getMappingTrans().startThreads();

          // The transformation still runs in the background and might have some
          // more work to do.
          // Since everything is running in the MappingThreads we don't have to do
          // anything else here but wait...
          //
          if ( getTransMeta().getTransformationType() == TransformationType.Normal ) {

View on GitHub (pinned to f3058517a1)