quarkusio/quarkus · error · IllegalStateException
@Compressed and @Uncompressed cannot be both declared on res
Error message
@Compressed and @Uncompressed cannot be both declared on resource method %s declared on %s
What it means
CompressionScanner inspects JAX-RS resource methods at build time to compute their HTTP compression setting from the Quarkus @Compressed and @Uncompressed annotations, which are mutually exclusive. If a single resource method is annotated with both, the scanner cannot decide the behavior and throws this IllegalStateException during deployment.
Source
Thrown at extensions/resteasy-reactive/rest/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/CompressionScanner.java:48
public CompressionScanner(VertxHttpBuildTimeConfig httpBuildTimeConfig) {
this.httpBuildTimeConfig = httpBuildTimeConfig;
}
@Override
public List<HandlerChainCustomizer> scan(MethodInfo method, ClassInfo actualEndpointClass,
Map<String, Object> methodContext) {
if (!httpBuildTimeConfig.enableCompression()) {
return Collections.emptyList();
}
AnnotationStore annotationStore = (AnnotationStore) methodContext.get(EndpointIndexer.METHOD_CONTEXT_ANNOTATION_STORE);
HttpCompression compression = HttpCompression.UNDEFINED;
if (annotationStore.hasAnnotation(method, COMPRESSED)) {
compression = HttpCompression.ON;
}
if (annotationStore.hasAnnotation(method, UNCOMPRESSED)) {
if (compression == HttpCompression.ON) {
throw new IllegalStateException(
String.format(
"@Compressed and @Uncompressed cannot be both declared on resource method %s declared on %s",
method, actualEndpointClass));
} else {
compression = HttpCompression.OFF;
}
}
if (compression == HttpCompression.OFF) {
// No action is needed because the "Content-Encoding: identity" header is set for every request if compression is enabled
return Collections.emptyList();
}
ResteasyReactiveCompressionHandler handler = new ResteasyReactiveCompressionHandler(
// Avoid using Set.copyOf() here as it creates SetN<E> with unstable iteration order.
// This leads to bytecode being unstable across builds. Prefer using HashSet wrapped
// in Collections.unmodifiableSet() instead.
Collections.unmodifiableSet(
new HashSet<>(httpBuildTimeConfig.compressMediaTypes().orElse(Collections.emptyList()))));
handler.setCompression(compression);View on GitHub (pinned to e1c734241f)
Solutions
- Remove one of the two annotations from the resource method, keeping only @Compressed or @Uncompressed.
- If both were inherited via meta-annotations, split the custom annotation into two or drop one layer.
- Let the method inherit class/global compression config (quarkus.resteasy reactive compression settings) by removing both annotations.
Example fix
// before
@Compressed
@Uncompressed // conflict
@GET
public String get() { ... }
// after
@Compressed
@GET
public String get() { ... } Defensive patterns
Strategy: validation
Validate before calling
static void assertNotBoth(Method m) {
boolean compressed = m.isAnnotationPresent(Compressed.class);
boolean uncompressed = m.isAnnotationPresent(Uncompressed.class);
if (compressed && uncompressed)
throw new IllegalStateException("@Compressed and @Uncompressed cannot both be on " + m);
} Try / catch
// Fails during Quarkus augmentation, not at runtime; guard in a unit test:
try {
runAugmentation();
} catch (IllegalStateException e) {
if (e.getMessage().contains("cannot be both declared")) {
log.error("Remove one of @Compressed/@Uncompressed: " + e.getMessage());
}
} Prevention
- Annotate a resource method with only one of @Compressed or @Uncompressed
- When switching compression mode, delete the old annotation rather than commenting it out
- Check meta-annotated custom annotations for conflicting nested annotations
When it happens
Trigger: Annotating the same resource method (in a class scanned as a REST endpoint) with both io.quarkus.resteasy.reactive.Compressed and Uncompressed, triggering RESTEasy Reactive server deployment scanning.
Common situations: Toggling compression during development and forgetting to remove the other annotation; inheriting/composing annotations from a meta-annotated custom annotation that carries both; merge conflicts adding both annotations.
Related errors
- Method '' of class '' contains multiple HTTP method annotati
- Cannot have more than one of @PathParam, @QueryParam, @Heade
- A resource method cannot be simultaneously annotated with '@
- The @Blocking, @NonBlocking and @RunOnVirtualThread annotati
- Value not set for ${param}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/f2248505004564bc.
Report an issue: GitHub.