{"record":{"id":"30ddd7a5769ec689","repo":"quarkusio/quarkus","slug":"method-of-class-contains-both-blocking-and","errorCode":null,"errorMessage":"Method '' of class '' contains both @Blocking and @NonBlocking annotations.","messagePattern":"Method '' of class '' contains both @Blocking and @NonBlocking annotations\\.","errorType":"validation","errorClass":"DeploymentException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java","lineNumber":922,"sourceCode":"            if (blockingAnnotation != null) {\n                return false;\n            } else {\n                return defaultValue == BlockingDefault.RUN_ON_VIRTUAL_THREAD;\n            }\n        }\n    }\n\n    private boolean isBlocking(MethodInfo info, BlockingDefault defaultValue) {\n        Map.Entry<AnnotationTarget, AnnotationInstance> blockingAnnotation = getInheritableAnnotation(info, BLOCKING);\n        Map.Entry<AnnotationTarget, AnnotationInstance> runOnVirtualThreadAnnotation = getInheritableAnnotation(info,\n                RUN_ON_VIRTUAL_THREAD);\n        Map.Entry<AnnotationTarget, AnnotationInstance> nonBlockingAnnotation = getInheritableAnnotation(info,\n                NON_BLOCKING);\n\n        if ((blockingAnnotation != null) && (nonBlockingAnnotation != null)) {\n            if (blockingAnnotation.getKey().kind() == nonBlockingAnnotation.getKey().kind()) {\n                if (blockingAnnotation.getKey().kind() == AnnotationTarget.Kind.METHOD) {\n                    throw new DeploymentException(\n                            \"Method '\" + info.name() + \"' of class '\" + info.declaringClass().name()\n                                    + \"' contains both @Blocking and @NonBlocking annotations.\");\n                } else {\n                    throw new DeploymentException(\"Class '\" + info.declaringClass().name()\n                            + \"' contains both @Blocking and @NonBlocking annotations.\");\n                }\n            }\n            if (blockingAnnotation.getKey().kind() == AnnotationTarget.Kind.METHOD) {\n                // the most specific annotation was the @Blocking annotation on the method\n                return true;\n            } else {\n                // the most specific annotation was the @NonBlocking annotation on the method\n                return false;\n            }\n        } else if ((blockingAnnotation != null)) {\n            return true;\n        } else if ((nonBlockingAnnotation != null)) {\n            return false;","sourceCodeStart":904,"sourceCodeEnd":940,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java#L904-L940","documentation":"A method cannot be annotated with both @Blocking and @NonBlocking — the desired execution model would be ambiguous. EndpointIndexer detects the conflict and throws this DeploymentException when both annotations target the same method (same annotation target kind METHOD).","triggerScenarios":"Deploying a resource method that (after annotation inheritance/inheritable lookup) resolves to having both a @Blocking and a @NonBlocking annotation directly on the method.","commonSituations":"Copy-pasting annotations from another endpoint; a merge conflict leaving both annotations in place; IDE auto-import adding @NonBlocking next to an existing @Blocking while experimenting with threading behavior.","solutions":["Remove the @NonBlocking annotation from the method, keeping @Blocking","Or remove @Blocking and keep @NonBlocking if the method is reactive","Decide one execution model per method based on whether it performs blocking I/O"],"exampleFix":"// before\n@Blocking\n@NonBlocking\npublic String get() { ... }\n// after\n@Blocking\npublic String get() { ... }","handlingStrategy":"validation","validationCode":"Method m = MyResource.class.getMethod(\"get\");\nif (m.isAnnotationPresent(Blocking.class) && m.isAnnotationPresent(NonBlocking.class)) {\n    throw new IllegalStateException(\"Both @Blocking and @NonBlocking on \" + m);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Choose one execution model per method: blocking I/O => @Blocking, reactive => @NonBlocking","Watch for copy-paste and merge conflicts around threading annotations","Check superclass/interface annotations that may conflict via inheritance","Add CI annotation-scanning tests for resource classes"],"tags":["quarkus","resteasy-reactive","blocking","nonblocking","deployment"],"backgroundTag":"conflicting-blocking-annotations","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"}