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
- Set the target slave before sending: executionConfiguration.setRemoteServer(slaveServer).
- Obtain the SlaveServer from the repository metadata or cluster schema instead of constructing ad hoc.
- If execution should be local, use the local execution path instead of sendToSlaveServer.
- 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
- Always call setRemoteServer before sendToSlaveServer.
- Load SlaveServer objects from the repository, not ad hoc construction.
- For local runs, use the local execution path instead of the remote sender.
- Centralize remote-exec configuration in one validated helper.
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
- DynamicSQLRow.Exception.SQLFieldNameEmpty
- ERROR0014
- GetTableNames.Log.NoSchemaField
- GPLoad.Exception.MatchColumnsNeeded
- Mail.Log.DestinationFieldEmpty
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)