{"record":{"id":"a08f3dcefe29e97e","repo":"quarkusio/quarkus","slug":"invalid-combination-a-reactive-route-cannot-use","errorCode":null,"errorMessage":"Invalid combination - a reactive route cannot use @Blocking and use the type `failure` at the same time: ","messagePattern":"Invalid combination - a reactive route cannot use @Blocking and use the type `failure` at the same time: ","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/reactive-routes/deployment/src/main/java/io/quarkus/vertx/web/deployment/ReactiveRoutesProcessor.java","lineNumber":432,"sourceCode":"                if (route.value(VALUE_CONSUMES) == null && baseConsumes != null) {\n                    consumes = baseConsumes;\n                }\n\n                HandlerType handlerType = HandlerType.NORMAL;\n                if (routeHandlerType != null) {\n                    handlerType = switch (routeHandlerType) {\n                        case NORMAL -> HandlerType.NORMAL;\n                        case BLOCKING -> HandlerType.BLOCKING;\n                        case FAILURE -> HandlerType.FAILURE;\n                        default -> throw new IllegalStateException(\"Unknown type \" + routeHandlerType);\n                    };\n                }\n\n                if (businessMethod.isBlocking()) {\n                    if (handlerType == HandlerType.NORMAL) {\n                        handlerType = HandlerType.BLOCKING;\n                    } else if (handlerType == HandlerType.FAILURE) {\n                        throw new IllegalStateException(\n                                \"Invalid combination - a reactive route cannot use @Blocking and use the type `failure` at the same time: \"\n                                        + businessMethod.getMethod().toString());\n                    }\n                }\n\n                if (routeHandler == null) {\n                    String handlerClass = generateHandler(\n                            new HandlerDescriptor(businessMethod.getMethod(), beanValidationAnnotations.orElse(null),\n                                    handlerType == HandlerType.FAILURE, produces),\n                            businessMethod.getBean(), businessMethod.getMethod(), gizmo, transformedAnnotations,\n                            route, reflectiveHierarchy, produces.length > 0 ? produces[0] : null,\n                            validatorAvailable, index);\n                    reflectiveClasses\n                            .produce(ReflectiveClassBuildItem.builder(handlerClass).build());\n                    routeHandler = recorder.createHandler(handlerClass);\n                    routeHandlers.put(routeString, routeHandler);\n                }\n","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/reactive-routes/deployment/src/main/java/io/quarkus/vertx/web/deployment/ReactiveRoutesProcessor.java#L414-L450","documentation":"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.","triggerScenarios":"A method combining @Blocking (or a blocking method signature, e.g. returning non-reactive types that force blocking) with @Route(type = RouteHandlerType.FAILURE).","commonSituations":"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.","solutions":["Remove @Blocking from the method annotated with type = RouteHandlerType.FAILURE","Or remove type = FAILURE so the method is treated as a normal blocking route","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)"],"exampleFix":"// before\n@Blocking\n@Route(path = \"/err\", type = RouteHandlerType.FAILURE)\npublic void handle(RoutingContext rc) { ... }\n// after\n@Route(path = \"/err\", type = RouteHandlerType.FAILURE)\npublic void handle(RoutingContext rc) { /* non-blocking only */ }","handlingStrategy":"validation","validationCode":"if (method.isAnnotatedWith(Blocking.class)\n        && route.type() == RouteHandlerType.FAILURE) {\n    throw new IllegalStateException(\n        method + \" cannot be @Blocking and type=FAILURE\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never add @Blocking to type=FAILURE routes","Keep failure handlers non-blocking; offload heavy work to worker beans","Code-review route annotations after refactors"],"tags":["quarkus","reactive-routes","blocking","vertx"],"backgroundTag":"blocking-route-failure-conflict","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}