quarkusio/quarkus · error · java.lang.IllegalStateException

Invalid combination - a reactive route cannot use @Blocking

Error message

Invalid combination - a reactive route cannot use @Blocking and use the type `failure` at the same time: 

What it means

A reactive route business method annotated @Blocking cannot also declare handler type FAILURE: blocking failure handling is unsupported by the processor. When addAdditionalRoutes sees isBlocking() with HandlerType.FAILURE it throws IllegalStateException pointing at the offending method signature.

Source

Thrown at extensions/reactive-routes/deployment/src/main/java/io/quarkus/vertx/web/deployment/ReactiveRoutesProcessor.java:432

                if (route.value(VALUE_CONSUMES) == null && baseConsumes != null) {
                    consumes = baseConsumes;
                }

                HandlerType handlerType = HandlerType.NORMAL;
                if (routeHandlerType != null) {
                    handlerType = switch (routeHandlerType) {
                        case NORMAL -> HandlerType.NORMAL;
                        case BLOCKING -> HandlerType.BLOCKING;
                        case FAILURE -> HandlerType.FAILURE;
                        default -> throw new IllegalStateException("Unknown type " + routeHandlerType);
                    };
                }

                if (businessMethod.isBlocking()) {
                    if (handlerType == HandlerType.NORMAL) {
                        handlerType = HandlerType.BLOCKING;
                    } else if (handlerType == HandlerType.FAILURE) {
                        throw new IllegalStateException(
                                "Invalid combination - a reactive route cannot use @Blocking and use the type `failure` at the same time: "
                                        + businessMethod.getMethod().toString());
                    }
                }

                if (routeHandler == null) {
                    String handlerClass = generateHandler(
                            new HandlerDescriptor(businessMethod.getMethod(), beanValidationAnnotations.orElse(null),
                                    handlerType == HandlerType.FAILURE, produces),
                            businessMethod.getBean(), businessMethod.getMethod(), gizmo, transformedAnnotations,
                            route, reflectiveHierarchy, produces.length > 0 ? produces[0] : null,
                            validatorAvailable, index);
                    reflectiveClasses
                            .produce(ReflectiveClassBuildItem.builder(handlerClass).build());
                    routeHandler = recorder.createHandler(handlerClass);
                    routeHandlers.put(routeString, routeHandler);
                }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove @Blocking from the method annotated with type = RouteHandlerType.FAILURE
  2. Or remove type = FAILURE so the method is treated as a normal blocking route
  3. If blocking work is needed on failure, keep the failure route non-blocking and delegate to a worker thread (e.g. Vertx.executeBlocking or a CDI bean offloaded with @Blocking elsewhere)

Example fix

// before
@Blocking
@Route(path = "/err", type = RouteHandlerType.FAILURE)
public void handle(RoutingContext rc) { ... }
// after
@Route(path = "/err", type = RouteHandlerType.FAILURE)
public void handle(RoutingContext rc) { /* non-blocking only */ }
Defensive patterns

Strategy: validation

Validate before calling

if (method.isAnnotatedWith(Blocking.class)
        && route.type() == RouteHandlerType.FAILURE) {
    throw new IllegalStateException(
        method + " cannot be @Blocking and type=FAILURE");
}

Prevention

When it happens

Trigger: A method combining @Blocking (or a blocking method signature, e.g. returning non-reactive types that force blocking) with @Route(type = RouteHandlerType.FAILURE).

Common situations: Adding @Blocking to an existing failure route to do blocking error logging; copy-pasting a failure handler from a non-blocking route; annotations added by refactoring tools.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/a08f3dcefe29e97e. Report an issue: GitHub.