pentaho/pentaho-kettle · error · KettleException

No slave server specified

Error message

No slave server specified

What it means

Thrown by the static Trans.sendToSlaveServer(...) when sending a transformation for remote/clustered execution but the execution configuration has no remote server set: executionConfiguration.getRemoteServer() returned null, so there is nowhere to send the transformation.

Solutions

  1. Set the target slave before sending: executionConfiguration.setRemoteServer(slaveServer).
  2. Obtain the SlaveServer from the repository metadata or cluster schema instead of constructing ad hoc.
  3. If execution should be local, use the local execution path instead of sendToSlaveServer.
  4. Validate the configuration (remote server non-null) before invoking sendToSlaveServer.

Example fix

// before
Trans.sendToSlaveServer(transMeta, executionConfiguration, repository, metaStore);
// after
if (executionConfiguration.getRemoteServer() == null) {
  executionConfiguration.setRemoteServer(repository.loadSlaveServer("carte-slave-1", null));
}
Trans.sendToSlaveServer(transMeta, executionConfiguration, repository, metaStore);
Defensive patterns

Strategy: validation

Validate before calling

if (executionConfiguration == null || executionConfiguration.getRemoteServer() == null) {
  throw new IllegalArgumentException("executionConfiguration.remoteServer must be set before remote execution");
}
Trans.sendToSlaveServer(transMeta, executionConfiguration, repository, metaStore);

Type guard

boolean hasRemoteServer(TransExecutionConfiguration c) {
  return c != null && c.getRemoteServer() != null;
}

Try / catch

try {
  Trans.sendToSlaveServer(transMeta, config, repository, metaStore);
} catch (KettleException e) {
  if ("No slave server specified".equals(e.getMessage())) {
    log.error("Remote server not configured; set executionConfiguration.setRemoteServer(...)", e);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling Trans.sendToSlaveServer (directly or via Spoon's 'Run remotely') with a TransExecutionConfiguration whose remoteServer property was never set (setRemoteServer not called or set to null).

Common situations: Programmatic remote execution where the developer forgot setRemoteServer(slaveServer); configuration loaded from XML/JSON lacking the remote server entry; UI selection of slave lost before send.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

    return result;
  }

  /**
   * Send the transformation for execution to a Carte slave server.
   *
   * @param transMeta              the transformation meta-data
   * @param executionConfiguration the transformation execution configuration
   * @param repository             the repository
   * @return The Carte object ID on the server.
   * @throws KettleException if any errors occur during the dispatch to the slave server
   */
  public static String sendToSlaveServer( TransMeta transMeta, TransExecutionConfiguration executionConfiguration,
                                          Repository repository, IMetaStore metaStore ) throws KettleException {
    String carteObjectId;
    SlaveServer slaveServer = executionConfiguration.getRemoteServer();

    if ( slaveServer == null ) {
      throw new KettleException( "No slave server specified" );
    }
    if ( Utils.isEmpty( transMeta.getName() ) ) {
      throw new KettleException( "The transformation needs a name to uniquely identify it by on the remote server." );
    }

    // Inject certain internal variables to make it more intuitive.
    //
    Map<String, String> vars = new HashMap<>();

    for ( String var : Const.INTERNAL_TRANS_VARIABLES ) {
      vars.put( var, transMeta.getVariable( var ) );
    }
    for ( String var : Const.INTERNAL_JOB_VARIABLES ) {
      vars.put( var, transMeta.getVariable( var ) );
    }

    executionConfiguration.getVariables().putAll( vars );
    slaveServer.injectVariables( executionConfiguration.getVariables() );

View on GitHub (pinned to f3058517a1)