quarkusio/quarkus · error · DeploymentException
Class '' contains both @Blocking and @NonBlocking annotation
Error message
Class '' contains both @Blocking and @NonBlocking annotations.
What it means
A class cannot declare both @Blocking and @NonBlocking — the default execution model for all its methods would be ambiguous. When EndpointIndexer finds both annotations on the class (same target kind CLASS, not METHOD), deployment fails with this DeploymentException.
Source
Thrown at independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java:926
}
}
}
private boolean isBlocking(MethodInfo info, BlockingDefault defaultValue) {
Map.Entry<AnnotationTarget, AnnotationInstance> blockingAnnotation = getInheritableAnnotation(info, BLOCKING);
Map.Entry<AnnotationTarget, AnnotationInstance> runOnVirtualThreadAnnotation = getInheritableAnnotation(info,
RUN_ON_VIRTUAL_THREAD);
Map.Entry<AnnotationTarget, AnnotationInstance> nonBlockingAnnotation = getInheritableAnnotation(info,
NON_BLOCKING);
if ((blockingAnnotation != null) && (nonBlockingAnnotation != null)) {
if (blockingAnnotation.getKey().kind() == nonBlockingAnnotation.getKey().kind()) {
if (blockingAnnotation.getKey().kind() == AnnotationTarget.Kind.METHOD) {
throw new DeploymentException(
"Method '" + info.name() + "' of class '" + info.declaringClass().name()
+ "' contains both @Blocking and @NonBlocking annotations.");
} else {
throw new DeploymentException("Class '" + info.declaringClass().name()
+ "' contains both @Blocking and @NonBlocking annotations.");
}
}
if (blockingAnnotation.getKey().kind() == AnnotationTarget.Kind.METHOD) {
// the most specific annotation was the @Blocking annotation on the method
return true;
} else {
// the most specific annotation was the @NonBlocking annotation on the method
return false;
}
} else if ((blockingAnnotation != null)) {
return true;
} else if ((nonBlockingAnnotation != null)) {
return false;
}
if (defaultValue == BlockingDefault.BLOCKING) {
return true;View on GitHub (pinned to e1c734241f)
Solutions
- Remove @NonBlocking from the class, keeping @Blocking as the class default
- Or remove @Blocking and keep @NonBlocking if the endpoints are reactive
- Move the specific annotation to individual methods instead of mixing at class level
Example fix
// before
@Blocking
@NonBlocking
@Path("/items")
public class ItemResource { ... }
// after
@Blocking
@Path("/items")
public class ItemResource { ... } Defensive patterns
Strategy: validation
Validate before calling
Class<?> c = MyResource.class;
if (c.isAnnotationPresent(Blocking.class) && c.isAnnotationPresent(NonBlocking.class)) {
throw new IllegalStateException("Both @Blocking and @NonBlocking on class " + c.getName());
}
// also check superclasses/interfaces for inherited conflicts
Class<?> s = c.getSuperclass();
while (s != null && s != Object.class) {
if (s.isAnnotationPresent(Blocking.class) && c.isAnnotationPresent(NonBlocking.class))
throw new IllegalStateException("Inherited @Blocking conflicts with class @NonBlocking");
s = s.getSuperclass();
} Prevention
- Set the class default once — either @Blocking or @NonBlocking — and override per method only
- Audit base resource classes for threading annotations before subclassing
- Avoid bulk-annotating whole classes during reactive migrations
- Document the class-level threading policy in the API module
When it happens
Trigger: Deploying a resource class annotated with both @Blocking and @NonBlocking at class level; annotations inherited from a superclass/interface that together yield both.
Common situations: Class-level annotation experimentation left in place; inheritance from a base resource class that carries the opposite annotation; bulk refactoring applying @NonBlocking to a class already marked @Blocking.
Related errors
- Method '' of class '' contains both @Blocking and @NonBlocki
- Endpoints that produce a Multipart result can only be used o
- Method '' of class '' is considered a non blocking method. @
- Parameter: ${i} of the constructor of class '${resourceDotNa
- Unable to load handled exception type ${i.getProvidedType()}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/f85b7b74c81c028f.
Report an issue: GitHub.