quarkusio/quarkus · error · IllegalStateException

Cannot generate HAL endpoints without either 'quarkus-restea

Error message

Cannot generate HAL endpoints without either 'quarkus-resteasy-jsonb' or 'quarkus-resteasy-jackson'

What it means

During deployment, Quarkus REST Data with Panache generates JAX-RS resource methods. When HAL (hypertext application language) endpoints are requested (resourceProperties.isHal()), the processor requires a JSON serializer extension present, because HAL responses are produced by the JSON provider. If RESTEasy Classic is detected and neither quarkus-resteasy-jsonb nor quarkus-resteasy-jackson is on the classpath, the build fails with this IllegalStateException.

Source

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

        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'");
                    } else if (!isResteasyClassic && !hasAnyJsonCapabilityForResteasyReactive(capabilities)) {
                        throw new IllegalStateException("Cannot generate HAL endpoints without "
                                + "either 'quarkus-rest-jsonb' or 'quarkus-rest-jackson'");
                    }

                }
                if (resourceProperties.isExposed()) {
                    jaxRsResourceImplementor.implement(classOutput, resourceMetadata, resourceProperties, capabilities);
                }
            }
        }
    }

    private ResourceProperties getResourceProperties(ResourcePropertiesProvider resourcePropertiesProvider,
            ResourceMetadata resourceMetadata, List<ResourcePropertiesBuildItem> resourcePropertiesBuildItems) {
        for (ResourcePropertiesBuildItem resourcePropertiesBuildItem : resourcePropertiesBuildItems) {
            if (resourcePropertiesBuildItem.getResourceType().equals(resourceMetadata.getResourceClass())

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add io.quarkus:quarkus-resteasy-jackson (or quarkus-resteasy-jsonb) to the pom.xml/build.gradle dependencies.
  2. If the app is RESTEasy Reactive, instead add quarkus-rest-jackson (or quarkus-rest-jsonb).
  3. Disable HAL generation for the resource (remove hal=true) if HAL links are not needed.

Example fix

// before (pom.xml): only classic REST + panache rest-data
<dependency>io.quarkus:quarkus-resteasy</dependency>
// after
<dependency>io.quarkus:quarkus-resteasy</dependency>
<dependency>io.quarkus:quarkus-resteasy-jackson</dependency>
Defensive patterns

Strategy: validation

Validate before calling

// pom.xml / build check before building
boolean classic = hasDependency("io.quarkus:quarkus-resteasy");
boolean ok = classic
    ? hasDependency("io.quarkus:quarkus-resteasy-jackson") || hasDependency("io.quarkus:quarkus-resteasy-jsonb")
    : hasDependency("io.quarkus:quarkus-rest-jackson") || hasDependency("io.quarkus:quarkus-rest-jsonb");
if (!ok) throw new IllegalStateException("HAL endpoints need a RESTEasy JSON extension");

Prevention

When it happens

Trigger: Build time: a Panache resource is exposed with HAL enabled (e.g. @ResourceProperties(hal = true) or quarkus.rest-data-panache... hal config) while the application uses RESTEasy Classic and has no RESTEasy Classic JSON provider (quarkus-resteasy-jsonb or quarkus-resteasy-jackson) among its capabilities.

Common situations: Developer adds a REST Data Panache resource with HAL links enabled but only pulled in quarkus-resteasy (no JSON mapper); app was migrated to/from RESTEasy Reactive leaving the wrong JSON extension set; missing the quarkus-resteasy-jackson dependency after removing quarkus-hibernate-orm-panache which used to pull it transitively.

Related errors


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