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

  1. Remove one of the two annotations from the resource method, keeping only @Compressed or @Uncompressed.
  2. If both were inherited via meta-annotations, split the custom annotation into two or drop one layer.
  3. 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

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


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