quarkusio/quarkus · error · IllegalStateException
Unable to create route handler: " + handlerClassName
Error message
Unable to create route handler: " + handlerClassName
What it means
VertxWebRecorder.createHandler loads a handler class generated at build time and instantiates it reflectively at startup. If the class cannot be loaded or instantiated (missing, wrong name, or no no-arg constructor), an IllegalStateException wrapping the reflective cause is thrown.
Source
Thrown at extensions/reactive-routes/runtime/src/main/java/io/quarkus/vertx/web/runtime/VertxWebRecorder.java:50
VertxHttpBuildTimeConfig httpBuildTimeConfig) {
this.httpConfig = httpConfig;
this.httpBuildTimeConfig = httpBuildTimeConfig;
}
@SuppressWarnings("unchecked")
public Handler<RoutingContext> createHandler(String handlerClassName) {
try {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) {
cl = VertxWebRecorder.class.getClassLoader();
}
Class<? extends Handler<RoutingContext>> handlerClazz = (Class<? extends Handler<RoutingContext>>) cl
.loadClass(handlerClassName);
RouteHandler handler = (RouteHandler) handlerClazz.getDeclaredConstructor().newInstance();
return handler;
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | NoSuchMethodException
| InvocationTargetException e) {
throw new IllegalStateException("Unable to create route handler: " + handlerClassName, e);
}
}
public Handler<RoutingContext> runOnVirtualThread(Handler<RoutingContext> routeHandler) {
return new VirtualThreadsRouteHandler(routeHandler);
}
public Handler<RoutingContext> compressRouteHandler(Handler<RoutingContext> routeHandler, HttpCompression compression) {
if (httpBuildTimeConfig.enableCompression()) {
return new HttpCompressionHandler(routeHandler, compression,
compression == HttpCompression.UNDEFINED
? Set.copyOf(httpBuildTimeConfig.compressMediaTypes().orElse(List.of()))
: Set.of());
} else {
return routeHandler;
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Run a clean rebuild (./mvnw clean install) so generated handler classes match the current code.
- Verify the handlerClassName corresponds to a class generated by ReactiveRoutesProcessor and the extension versions are aligned.
- For native builds, ensure the generated handler class is registered for reflection (Quarkus normally does this automatically; check for custom exclude patterns in native configuration).
Defensive patterns
Strategy: try-catch
Validate before calling
// validate the class exists and is instantiable before use
Class<?> c = Class.forName(handlerClassName);
if (!Handler.class.isAssignableFrom(c) || c.getDeclaredConstructors()[0].getParameterCount() != 0)
throw new IllegalStateException("Invalid handler class: " + handlerClassName); Try / catch
try {
return recorder.createHandler(name);
} catch (IllegalStateException e) {
log.error("Handler {} missing; rebuilding? cause={}", name, e.getCause());
throw e;
} Prevention
- Run clean builds after refactoring generated handler names
- Keep quarkus-reactive-routes and quarkus-vertx-http versions aligned
- Verify reflection registration for native image builds
- Never hardcode generated handler class names
When it happens
Trigger: Calling VertxWebRecorder.createHandler with a handlerClassName that was not generated by ReactiveRoutesProcessor, refers to a class removed/renamed between builds, or has no public no-arg constructor.
Common situations: Stale build artifacts after refactoring generated handler names; mixing versions of quarkus-vertx-http and quarkus-reactive-routes; custom code calling the recorder directly with a mistyped class name; native-image builds where the class was not registered for reflection.
Related errors
- Failed to load steps from %s
- The class (${name}) cannot be created during deployment.
- Couldn't extract all parameters information for constructor
- The class (${name}) cannot be created during deployment.
- Unable to find main method on class '${originalMainClassName
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/8032cef7e8eedc6e.
Report an issue: GitHub.