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
- Remove io.quarkus:quarkus-resteasy and any quarkus-resteasy-* classic dependencies
- Ensure io.quarkus:quarkus-rest is present as the JAX-RS layer
- Run mvn dependency:tree -Dincludes=io.quarkus:quarkus-resteasy to find what pulls the classic stack and exclude it there
- 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
- In reactive applications, exclude/quarantine any transitive quarkus-resteasy dependency
- Standardize on quarkus-rest for all new services using Hibernate Reactive
- Verify with dependency:tree when adding new extensions that might pull the classic stack
- Keep one REST stack per application; document the choice in the team's project template
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
- REST Data Panache can only work if 'quarkus-rest' or 'quarku
- Cannot generate HAL endpoints without either 'quarkus-restea
- Cannot generate HAL endpoints without either 'quarkus-rest-j
- The class (${className}) cannot be found during deployment.
- Unsupported object of type ${object.getClass()}. Supported t
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/2f06ed4790ed9b6c.
Report an issue: GitHub.