quarkusio/quarkus · critical · IllegalStateException

Reactive REST Data Panache does not work with 'quarkus-reste

Error message

Reactive REST Data Panache does not work with 'quarkus-resteasy'. Only 'quarkus-rest' extensions are supported

What it means

RestDataProcessor.implementResources rejects the combination of Hibernate Reactive (reactive REST Data Panache resources) with RESTEasy Classic. Reactive Panache resources return Uni/Multi and require the reactive JAX-RS runtime (quarkus-rest); mixing them with the blocking classic stack is unsupported, so the build fails with IllegalStateException.

Source

Thrown at extensions/panache/rest-data-panache/deployment/src/main/java/io/quarkus/rest/data/panache/deployment/RestDataProcessor.java:70

                    .produce(new ContainerRequestFilterBuildItem.Builder(SortQueryParamFilter.class.getName())
                            .setNameBindingNames(Collections.singleton(SortQueryParamValidator.class.getName())).build());
        }
    }

    @BuildStep
    void implementResources(CombinedIndexBuildItem index,
            List<RestDataResourceBuildItem> resourceBuildItems,
            List<ResourcePropertiesBuildItem> resourcePropertiesBuildItems,
            List<BuildTimeConditionBuildItem> buildTimeConditions,
            Capabilities capabilities,
            BuildProducer<GeneratedBeanBuildItem> resteasyClassicImplementationsProducer,
            BuildProducer<GeneratedJaxRsResourceBuildItem> resteasyReactiveImplementationsProducer) {

        boolean isReactivePanache = capabilities.isPresent(Capability.HIBERNATE_REACTIVE);
        boolean isResteasyClassic = capabilities.isPresent(Capability.RESTEASY);

        if (isReactivePanache && isResteasyClassic) {
            throw new IllegalStateException(
                    "Reactive REST Data Panache does not work with 'quarkus-resteasy'. Only 'quarkus-rest' extensions are supported");
        }

        Set<String> excludedClasses = getExcludedClasses(buildTimeConditions);
        ClassOutput classOutput = isResteasyClassic ? new GeneratedBeanGizmoAdaptor(resteasyClassicImplementationsProducer)
                : new GeneratedJaxRsResourceGizmoAdaptor(resteasyReactiveImplementationsProducer);
        JaxRsResourceImplementor jaxRsResourceImplementor = new JaxRsResourceImplementor(capabilities);
        ResourcePropertiesProvider resourcePropertiesProvider = new ResourcePropertiesProvider(index.getIndex());

        for (RestDataResourceBuildItem resourceBuildItem : resourceBuildItems) {
            if (!excludedClasses.contains(resourceBuildItem.getResourceMetadata().getResourceName())) {
                ResourceMetadata resourceMetadata = resourceBuildItem.getResourceMetadata();
                ResourceProperties resourceProperties = getResourceProperties(resourcePropertiesProvider,
                        resourceMetadata, resourcePropertiesBuildItems);
                if (resourceProperties.isHal()) {
                    if (isResteasyClassic && !hasAnyJsonCapabilityForResteasyClassic(capabilities)) {
                        throw new IllegalStateException("Cannot generate HAL endpoints without "
                                + "either 'quarkus-resteasy-jsonb' or 'quarkus-resteasy-jackson'");

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove io.quarkus:quarkus-resteasy and any quarkus-resteasy-* classic dependencies
  2. Ensure io.quarkus:quarkus-rest is present as the JAX-RS layer
  3. Run mvn dependency:tree -Dincludes=io.quarkus:quarkus-resteasy to find what pulls the classic stack and exclude it there
  4. Switch reactive resources to the RESTEasy Reactive annotations (quarkus-rest) end-to-end

Example fix

// before (pom.xml)
<dependency>io.quarkus:quarkus-resteasy</dependency>
<dependency>io.quarkus:quarkus-hibernate-reactive</dependency>

// after
<dependency>io.quarkus:quarkus-rest</dependency>
<dependency>io.quarkus:quarkus-hibernate-reactive</dependency>
Defensive patterns

Strategy: validation

Validate before calling

// ensure the classic stack is absent in a reactive project:
// mvn dependency:tree -Dincludes=io.quarkus:quarkus-resteasy
// expected: no output; if present, add an <exclusion> at the offending dependency

Try / catch

// build-time failure — no runtime catch is possible;
// remove quarkus-resteasy or switch to the blocking stack and rebuild

Prevention

When it happens

Trigger: Having both io.quarkus:quarkus-hibernate-reactive (or quarkus-reactive-panache-rest-data / reactive REST Data resources) and io.quarkus:quarkus-resteasy on the classpath when building, so isReactivePanache && isResteasyClassic both hold.

Common situations: Incremental migration where classic REST dependencies were never removed; including quarkus-resteasy transitively via another extension (e.g. a starter pulling the classic stack); copying dependencies from a classic-based example into a reactive project.

Related errors


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