pentaho/pentaho-kettle · error · KettleException
No slave server specified
Error message
No slave server specified
What it means
sendToSlaveServer() throws this KettleException when executionConfiguration.getRemoteServer() returns null, i.e. the caller requested remote/slated execution but never selected a slave (remote) server. The library cannot dispatch the job anywhere without a target Carte/Slave server.
Solutions
- Set the remote server before calling sendToSlaveServer: executionConfiguration.setRemoteServer(slaveServer).
- Load the slave server from the repository's cluster/slave schema instead of constructing it ad hoc.
- If local execution was intended, do not mark the execution configuration as remote/executing on a server.
- Verify slave registration so it appears in the available slave list to select.
Example fix
// before
JobExecutionConfiguration execCfg = new JobExecutionConfiguration();
execCfg.setExecutingRemotely(true); // remoteServer never set
Job.sendToSlaveServer(jobMeta, execCfg, repo, metaStore);
// after
SlaveServer remote = new SlaveServer("carte1", "carte1.example.com", "8080", "cluster", "cluster");
execCfg.setRemoteServer(remote);
execCfg.setExecutingRemotely(true);
Job.sendToSlaveServer(jobMeta, execCfg, repo, metaStore); Defensive patterns
Strategy: validation
Validate before calling
if (execCfg.isExecutingRemotely() && execCfg.getRemoteServer() == null) {
throw new IllegalArgumentException("Remote server must be set for remote execution");
} Try / catch
try {
Job.sendToSlaveServer(jobMeta, execCfg, repo, metaStore);
} catch (KettleException e) {
if (execCfg.getRemoteServer() == null) {
throw new ConfigurationException("No slave server configured", e);
}
throw e;
} Prevention
- Always pair setExecutingRemotely(true) with setRemoteServer(...).
- Load slave definitions from the repository rather than hardcoding.
- Validate the execution configuration before submission with a small preflight method.
- Keep slave registrations in clusters so selection cannot be forgotten.
When it happens
Trigger: Calling Job.sendToSlaveServer(jobMeta, executionConfiguration, repository, metaStore) while JobExecutionConfiguration.remoteServer is unset; enabling 'execute remotely' in a caller (e.g. Spoon/Kitchen) without picking a remote host.
Common situations: Programmatic execution configurations built by hand that skip setRemoteServer(); UI metadata lost after export/import; cluster/slated setup where the master has no registered slaves.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- No slave server specified
- A connection of type PALO is expected
- A server socket allocation always has to accompanied by…
- AccessInput.Exception.CouldnotFindField
- AccessInput.Log.NoField
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/821ff19c669cdf50.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/job/Job.java:1721
* @param jobMeta
* the job meta
* @param executionConfiguration
* the execution configuration
* @param repository
* the repository
* @param metaStore
* the metaStore
* @return the string
* @throws KettleException
* the kettle exception
*/
public static String sendToSlaveServer( JobMeta jobMeta, JobExecutionConfiguration executionConfiguration,
Repository repository, IMetaStore metaStore ) throws KettleException {
String carteObjectId;
SlaveServer slaveServer = executionConfiguration.getRemoteServer();
if ( slaveServer == null ) {
throw new KettleException( BaseMessages.getString( PKG, "Job.Log.NoSlaveServerSpecified" ) );
}
if ( Utils.isEmpty( jobMeta.getName() ) ) {
throw new KettleException( BaseMessages.getString( PKG, "Job.Log.UniqueJobName" ) );
}
// Align logging levels between execution configuration and remote server
slaveServer.getLogChannel().setLogLevel( executionConfiguration.getLogLevel() );
try {
// Inject certain internal variables to make it more intuitive.
//
for ( String var : Const.INTERNAL_TRANS_VARIABLES ) {
executionConfiguration.getVariables().put( var, jobMeta.getVariable( var ) );
}
for ( String var : Const.INTERNAL_JOB_VARIABLES ) {
executionConfiguration.getVariables().put( var, jobMeta.getVariable( var ) );
}
View on GitHub (pinned to f3058517a1)