quarkusio/quarkus · error · IllegalStateException
Unable to create invoker:
Error message
Unable to create invoker:
What it means
SchedulerContext.createInvoker() loads the generated ScheduledInvoker class (recorded at build time) by name from the thread context classloader and instantiates it reflectively. If loading or construction fails (class missing, wrong classloader, constructor issue), it wraps the cause in this IllegalStateException including the invoker class name.
Source
Thrown at extensions/scheduler/common/src/main/java/io/quarkus/scheduler/common/runtime/SchedulerContext.java:33
boolean forceSchedulerStart();
List<ScheduledMethod> getScheduledMethods(String implementation);
boolean matchesImplementation(Scheduled scheduled, String implementation);
String autoImplementation();
@SuppressWarnings("unchecked")
default ScheduledInvoker createInvoker(String invokerClassName) {
try {
Class<? extends ScheduledInvoker> invokerClazz = (Class<? extends ScheduledInvoker>) Thread.currentThread()
.getContextClassLoader()
.loadClass(invokerClassName);
return invokerClazz.getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | NoSuchMethodException
| InvocationTargetException e) {
throw new IllegalStateException("Unable to create invoker: " + invokerClassName, e);
}
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Ensure scheduler startup runs on a thread whose context classloader is the Quarkus runtime classloader (use Arc.container() or the app classloader explicitly)
- Rebuild the application so generated invoker classes are present; don't strip build-time generated sources
- In tests, bootstrap with @QuarkusTest rather than manually constructing SchedulerContext
- Inspect the wrapped cause (InstantiationException/ClassNotFoundException etc.) to pinpoint whether it's a classloading or construction problem
Example fix
// before (custom bootstrap, wrong classloader)
Thread.currentThread().setContextClassLoader(someLibLoader);
SchedulerContext.createInvoker("...Invoker");
// after
Thread.currentThread().setContextClassLoader(appClassloader); // Quarkus runtime CL
SchedulerContext.createInvoker("com.example.MyJob_Invoker"); Defensive patterns
Strategy: try-catch
Validate before calling
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
Class.forName(invokerClassName, false, cl);
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Invoker class not visible from TCCL: " + invokerClassName, e);
} Try / catch
try {
invoker = schedulerContext.createInvoker(className);
} catch (IllegalStateException e) {
LOG.error("Failed to create scheduled invoker {} - check classloader/rebuild", className, e.getCause());
} Prevention
- Let Quarkus bootstrap the scheduler; avoid custom main/test harnesses with foreign classloaders
- Rebuild the app after changing scheduler-related code so invoker classes regenerate
- Avoid stripping generated classes from packaged artifacts
- Inspect getCause() (ClassNotFoundException vs InstantiationException) when debugging
When it happens
Trigger: The invoker class recorded by the scheduler deployment module cannot be loaded: wrong Thread.currentThread().getContextClassLoader() at scheduler startup; QuarkusClassLoader already closed (app shutdown/restart); generated class absent from the artifact; reflective instantiation failure (no default constructor, security manager restriction).
Common situations: Running the scheduler outside the Quarkus runtime classloader (custom main/tests); dev-mode hot reload while a scheduled job fires; shaded/fat-jar packaging dropping generated classes; scheduler initialized from a background thread with no app classloader context.
Related errors
- Unable to load class [<className>]
- Could not initialize mapped class ${className}
- Failed to load generated class %s
- Unable to start Scheduler
- Not a resolver:
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/c2872a21f1995b0b.
Report an issue: GitHub.