pentaho/pentaho-kettle · error · KettleException

An error occurred sending a slave transformation:

Error message

An error occurred sending a slave transformation: 

What it means

In executeClustered, each slave transformation's XML is registered on its Carte slave server; a non-OK WebResult causes this KettleException (per slave thread, captured into the errors array). The Carte-side message is appended to the message.

Solutions

  1. Check webResult.getMessage() (appended) and the errors[index] Throwable for the exact slave failure
  2. Confirm every slave in the cluster schema is running (curl the slave's status URL) and reachable on its port
  3. Look for duplicate registered transformations on the slave and clean up stale Carte registrations
  4. Match PDI/kettle versions across client, master, and slaves

Example fix

// before: slave 2 of 3 is down
slaves[2] = new SlaveServer("slave2", "dead-host", 8082, ...);
// after
slaves[2] = new SlaveServer("slave2", "live-host", 8082, "cluster", "cluster");
Defensive patterns

Strategy: validation

Validate before calling

// health-check all slaves before executeClustered
for (SlaveServer slave : clusterSchema.getSlaves()) {
  if (!slave.getSlaveServerMonitor().getStatusSummary().isRunning()) {
    throw new IllegalStateException("Slave down: " + slave.getName());
  }
}

Try / catch

try {
  TransSplitter splitter = Trans.executeClustered(transMeta, config);
} catch (KettleException e) {
  if (e.getMessage().startsWith("An error occurred sending a slave transformation:")) {
    logError("Slave registration failed: " + e.getMessage());
  } else { throw e; }
}

Prevention

When it happens

Trigger: executeClustered sends slaveTrans.getXML() to each slave via sendXML(..., RegisterTransServlet.CONTEXT_PATH + "/?xml=Y") and the slave responds with a failed WebResult.

Common situations: One or more Carte slaves are down, overloaded, or unreachable; slave rejects registration because of a name/ID conflict; version mismatch between client and slave PDI; network/firewall blocking the slave port.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/Trans.java:3862

                variables.put( Const.INTERNAL_VARIABLE_CLUSTER_SIZE, Integer.toString( slaves.length ) );
                variables.put( Const.INTERNAL_VARIABLE_CLUSTER_MASTER, "N" );

                // Parameters override the variables but they need to pass over the configuration too...
                //
                Map<String, String> params = slaveTransExecutionConfiguration.getParams();
                TransMeta ot = transSplitter.getOriginalTransformation();
                for ( String param : ot.listParameters() ) {
                  String value =
                    Const.NVL( ot.getParameterValue( param ), Const.NVL( ot.getParameterDefault( param ), ot
                      .getVariable( param ) ) );
                  params.put( param, value );
                }

                String slaveReply =
                  slaves[ index ].sendXML( transConfiguration.getXML(), RegisterTransServlet.CONTEXT_PATH + "/?xml=Y" );
                WebResult webResult = WebResult.fromXMLString( slaveReply );
                if ( !webResult.getResult().equalsIgnoreCase( WebResult.STRING_OK ) ) {
                  throw new KettleException( "An error occurred sending a slave transformation: " + webResult
                    .getMessage() );
                }
                carteObjectMap.put( slaveTrans, webResult.getId() );
              } catch ( Throwable t ) {
                errors[ index ] = t;
              }
            }
          };
          threads[ i ] = new Thread( runnable );
        }
      }

      // Start the slaves
      for ( int i = 0; i < threads.length; i++ ) {
        if ( threads[ i ] != null ) {
          threads[ i ].start();
        }
      }

View on GitHub (pinned to f3058517a1)