apache/flink · error · IllegalStateException
Multiple compatible client factories found for: {}.
Error message
Multiple compatible client factories found for:
{}. What it means
Thrown by DefaultExecutorServiceLoader.getExecutorFactory when more than one PipelineExecutorFactory reports isCompatibleWith(configuration) == true. The service loader discovers all factories via SPI and the configuration must unambiguously select exactly one executor (e.g., local, remote, yarn, kubernetes).
Source
Thrown at flink-core/src/main/java/org/apache/flink/core/execution/DefaultExecutorServiceLoader.java:83
if (factory != null && factory.isCompatibleWith(configuration)) {
compatibleFactories.add(factory);
}
} catch (Throwable e) {
if (e.getCause() instanceof NoClassDefFoundError) {
LOG.info("Could not load factory due to missing dependencies.");
} else {
throw e;
}
}
}
if (compatibleFactories.size() > 1) {
final String configStr =
configuration.toMap().entrySet().stream()
.map(e -> e.getKey() + "=" + e.getValue())
.collect(Collectors.joining("\n"));
throw new IllegalStateException(
"Multiple compatible client factories found for:\n" + configStr + ".");
}
if (compatibleFactories.isEmpty()) {
throw new IllegalStateException("No ExecutorFactory found to execute the application.");
}
return compatibleFactories.get(0);
}
@Override
public Stream<String> getExecutorNames() {
final ServiceLoader<PipelineExecutorFactory> loader =
ServiceLoader.load(PipelineExecutorFactory.class);
return StreamSupport.stream(loader.spliterator(), false)
.map(PipelineExecutorFactory::getName);
}View on GitHub (pinned to 2f3c205e92)
Solutions
- Set execution.target explicitly (e.g., yarn-application, kubernetes-application, remote, local) to disambiguate.
- Remove conflicting executor JARs from the classpath so only one is compatible.
- If a custom factory is involved, narrow its isCompatibleWith to match only its intended configuration.
Example fix
# before # ambiguous: both local and remote executors are compatible # after execution.target: yarn-application
Defensive patterns
Strategy: validation
Validate before calling
// Ensure execution.target is set unambiguously
String target = config.get(ExecutionOptions.TARGET);
if (target == null || target.isEmpty()) {
throw new IllegalStateException("execution.target must be set to disambiguate executor");
} Try / catch
try {
loader.getExecutorFactory(configuration);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Multiple compatible")) { /* set execution.target or remove JARs */ }
} Prevention
- Always set execution.target to a concrete value.
- Avoid shipping overlapping executor JARs.
- Narrow custom factory isCompatibleWith checks.
When it happens
Trigger: Multiple executor JARs on the classpath (e.g., both flink-clients and a yarn/k8s executor) where the configuration doesn't disambiguate via execution.target or deployment options. Conflicting or overlapping isCompatibleWith logic across factory implementations.
Common situations: Shipping multiple deployment JARs without setting execution.target. Custom PipelineExecutorFactory implementations with overly broad compatibility checks. Ambiguous 'execution.attached' or 'execution.target' settings.
Related errors
- Multiple compatible client factories found for: {}.
- No ClusterClientFactory found. If you were targeting a Yarn
- No ExecutorFactory found to execute the application.
- No cluster id was specified. Please specify a cluster to whi
- No valid command-line found.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/2f19d664852ee753.
Report an issue: GitHub.