quarkusio/quarkus · error · IllegalArgumentException
A failure route cannot be a blocking route
Error message
A failure route cannot be a blocking route
What it means
RouteBuildItem.Builder.asBlockingRoute() marks the route's handler to run on a worker thread; failure routes (handler type FAILURE) are incompatible with this mode, so the builder refuses the change with an IllegalArgumentException.
Source
Thrown at extensions/vertx-http/deployment-spi/src/main/java/io/quarkus/vertx/http/deployment/spi/RouteBuildItem.java:347
* Sets the request handler (mandatory)
*
* @param handler the handler, must not be {@code null}
* @return the current builder
*/
public Builder withRequestHandler(Handler<RoutingContext> handler) {
this.handler = handler;
return this;
}
/**
* Sets the route as a blocking route.
* A blocking route handler is invoked on a worker thread, and thus is allowed to block.
*
* @return the current builder
*/
public Builder asBlockingRoute() {
if (this.typeOfHandler == HandlerType.FAILURE) {
throw new IllegalArgumentException("A failure route cannot be a blocking route");
}
this.typeOfHandler = HandlerType.BLOCKING;
return this;
}
/**
* Sets the route as a failure route.
* A failure route handler is invoked when an exception is thrown from a route handler.
*
* @return the current builder
*/
public Builder asFailureRoute() {
if (this.typeOfHandler == HandlerType.BLOCKING) {
throw new IllegalArgumentException("A blocking route cannot be a failure route");
}
this.typeOfHandler = HandlerType.FAILURE;
return this;
}View on GitHub (pinned to e1c734241f)
Solutions
- Remove asFailureRoute() from the builder chain if a blocking route is intended
- Remove asBlockingRoute() if the route must remain a failure route
- If blocking work is needed in a failure handler, offload via executeBlocking/Uni inside the handler instead
Example fix
// before RouteBuildItem.builder().route(route).asFailureRoute().asBlockingRoute().build() // after RouteBuildItem.builder().route(route).asBlockingRoute().build()
Defensive patterns
Strategy: validation
Validate before calling
// decide the handler type once; never apply both boolean failure = ...; RouteBuildItem.Builder b = RouteBuildItem.builder().route(route); if (failure) b.asFailureRoute(); else b.asBlockingRoute();
Prevention
- Set exactly one of asBlockingRoute/asFailureRoute per builder
- Keep builder chains linear and reviewed for duplicate handler-type calls
- Document handler type in shared route-building helpers
When it happens
Trigger: Builder chain calls asFailureRoute() then asBlockingRoute() on the same builder (typeOfHandler == HandlerType.FAILURE).
Common situations: Copy-pasted builder chains toggling both handler types; refactoring an existing failure route to be blocking; a utility method that applies asBlockingRoute unconditionally.
Related errors
- A blocking route cannot be a failure route
- GeneratedStaticResourceBuildItem endpoint must start with '/
- GeneratedStaticResourceBuildItem endpoint must not end with
- Invalid fileName
- CardAction title is required
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/344e949facd3018d.
Report an issue: GitHub.