quarkusio/quarkus · error · IllegalStateException
Invalid scheduler implementations detected:
Error message
Invalid scheduler implementations detected:
What it means
When multiple scheduler implementations are discovered (each registered via a SchedulerImplementationBuildItem with a priority), the processor verifies that each implementation name is unique. Duplicate implementation identifiers make the composite/sorted selection ambiguous, so build fails listing the offending build items.
Source
Thrown at extensions/scheduler/deployment/src/main/java/io/quarkus/scheduler/deployment/SchedulerProcessor.java:126
static final String INVOKER_SUFFIX = "_ScheduledInvoker";
static final String NESTED_SEPARATOR = "$_";
@BuildStep
SchedulerImplementationBuildItem implementation() {
return new SchedulerImplementationBuildItem(Scheduled.SIMPLE, DotName.createSimple(SimpleScheduler.class), 0);
}
@BuildStep
void compositeScheduler(SchedulerConfig config, List<SchedulerImplementationBuildItem> implementations,
BuildProducer<AdditionalBeanBuildItem> additionalBeans,
BuildProducer<DiscoveredImplementationsBuildItem> discoveredImplementations) {
List<SchedulerImplementationBuildItem> sorted = implementations.stream()
.sorted(Comparator.comparingInt(SchedulerImplementationBuildItem::getPriority).reversed()).toList();
Set<String> found = sorted.stream().map(SchedulerImplementationBuildItem::getImplementation)
.collect(Collectors.toUnmodifiableSet());
if (found.size() != implementations.size()) {
throw new IllegalStateException("Invalid scheduler implementations detected: " + implementations);
}
DiscoveredImplementationsBuildItem discovered = new DiscoveredImplementationsBuildItem(
sorted.get(0).getImplementation(), found,
config.useCompositeScheduler());
discoveredImplementations.produce(discovered);
if (implementations.size() > 1 && config.useCompositeScheduler()) {
// If multiple implementations are needed we have to register the CompositeScheduler, and
// instruct the extensions that provide an implementation to modify the bean metadata, i.e. add the marker qualifier
additionalBeans.produce(AdditionalBeanBuildItem.builder()
.addBeanClasses(Constituent.class, CompositeScheduler.class).setUnremovable().build());
}
}
@BuildStep
void transformSchedulerBeans(DiscoveredImplementationsBuildItem discoveredImplementations,
List<SchedulerImplementationBuildItem> implementations,
BuildProducer<AnnotationsTransformerBuildItem> transformer) {
if (discoveredImplementations.isCompositeSchedulerUsed()) {View on GitHub (pinned to e1c734241f)
Solutions
- Remove one of the duplicate scheduler extensions/dependencies from the application
- Ensure your custom @BuildStep produces the SchedulerImplementationBuildItem only once
- Use a unique implementation name for custom scheduler implementations
- Check for duplicate/stale jars carrying the same scheduler implementation
Example fix
// before
@BuildStep
void implA(BuildProducer<SchedulerImplementationBuildItem> p) {
p.produce(new SchedulerImplementationBuildItem("quartz", 5, ...));
}
@BuildStep
void implB(BuildProducer<SchedulerImplementationBuildItem> p) {
p.produce(new SchedulerImplementationBuildItem("quartz", 5, ...)); // duplicate
}
// after: produce it once, or use a distinct name e.g. "my-scheduler" Defensive patterns
Strategy: validation
Validate before calling
Set<String> names = new HashSet<>();
for (SchedulerImplementationBuildItem i : implementations) {
if (!names.add(i.getImplementation()))
throw new IllegalStateException("Duplicate scheduler implementation: " + i.getImplementation());
} Try / catch
try { /* build */ } catch (IllegalStateException e) {
if (e.getMessage().startsWith("Invalid scheduler implementations")) { /* dedupe build steps */ }
} Prevention
- Use a unique implementation id per scheduler extension
- Produce SchedulerImplementationBuildItem exactly once
- Check dependency tree for duplicate scheduler extensions
- Name custom implementations distinctively
When it happens
Trigger: Two extensions (or the same extension registered twice) produce SchedulerImplementationBuildItems with the same implementation name string.
Common situations: Having both quarkus-quartz and a custom scheduler extension exposing the same implementation id; accidentally producing the build item twice in a custom @BuildStep; stale duplicate jars on the classpath.
Related errors
- Something went wrong during parameter type resolution - expe
- Non-static @Scheduled methods may not be declared on abstrac
- Failed to open path tree with root %s
- Dev services for ${request.getName()} requires a startable s
- Name cannot start with '/':${name}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/eb65cc578251a91f.
Report an issue: GitHub.