quarkusio/quarkus · error · IllegalStateException

Spring Web can only work if 'quarkus-resteasy-jackson' or 'q

Error message

Spring Web can only work if 'quarkus-resteasy-jackson' or 'quarkus-rest-jackson' is present

What it means

The Quarkus Spring Web extension translates Spring @ExceptionHandler/@ResponseStatus annotations into JAX-RS ExceptionMappers at build time, but it needs a JSON serializer to build response bodies. Neither the RESTEasy Classic JSON-Jackson nor the RESTEasy Reactive JSON-Jackson capability is present, so the processor aborts the build. This is a deliberate dependency check, not a runtime failure.

Source

Thrown at extensions/spring-web/core/deployment/src/main/java/io/quarkus/spring/web/deployment/SpringWebProcessor.java:150

        beanDefiningAnnotations
                .produce(new BeanDefiningAnnotationBuildItem(REST_CONTROLLER_ADVICE, BuiltinScope.SINGLETON.getName()));
    }

    @BuildStep
    public void exceptionHandlingSupport(CombinedIndexBuildItem index,
            BuildProducer<GeneratedClassBuildItem> generatedExceptionMappers,
            BuildProducer<GeneratedResourceBuildItem> generatedResources,
            BuildProducer<ResteasyJaxrsProviderBuildItem> providersProducer,
            BuildProducer<ExceptionMapperBuildItem> exceptionMapperProducer,
            BuildProducer<ReflectiveClassBuildItem> reflectiveClassProducer,
            BuildProducer<UnremovableBeanBuildItem> unremovableBeanProducer,
            Capabilities capabilities) {

        boolean isResteasyClassicAvailable = capabilities.isPresent(Capability.RESTEASY_JSON_JACKSON);
        boolean isResteasyReactiveAvailable = capabilities.isPresent(Capability.RESTEASY_REACTIVE_JSON_JACKSON);

        if (!isResteasyClassicAvailable && !isResteasyReactiveAvailable) {
            throw new IllegalStateException(
                    "Spring Web can only work if 'quarkus-resteasy-jackson' or 'quarkus-rest-jackson' is present");
        }

        TypesUtil typesUtil = new TypesUtil(Thread.currentThread().getContextClassLoader());

        // Look for all exception classes that are annotated with @ResponseStatus

        IndexView indexView = index.getIndex();
        ClassOutput classOutput = new GeneratedClassGizmo2Adaptor(generatedExceptionMappers, generatedResources, true);
        generateMappersForResponseStatusOnException(providersProducer, exceptionMapperProducer, indexView, classOutput,
                typesUtil,
                isResteasyClassicAvailable);
        generateMappersForExceptionHandlerInControllerAdvice(providersProducer, exceptionMapperProducer,
                reflectiveClassProducer, unremovableBeanProducer, indexView, classOutput,
                typesUtil, isResteasyClassicAvailable);
    }

    private void generateMappersForResponseStatusOnException(BuildProducer<ResteasyJaxrsProviderBuildItem> providersProducer,

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add quarkus-rest-jackson (RESTEasy Reactive) or quarkus-resteasy-jackson (Classic) to pom.xml/build.gradle.
  2. Verify with mvn dependency:tree that a jackson REST extension is actually resolved and not excluded.
  3. If you don't need Spring Web compat, remove the quarkus-spring-web extension instead.

Example fix

// before (pom.xml)
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-spring-web</artifactId>
</dependency>

// after
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-spring-web</artifactId>
</dependency>
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-rest-jackson</artifactId>
</dependency>
Defensive patterns

Strategy: validation

Validate before calling

// build-time check: verify pom.xml includes one of
// io.quarkus:quarkus-rest-jackson OR io.quarkus:quarkus-resteasy-jackson
// shell: mvn dependency:tree | grep -E 'quarkus-(rest|resteasy)-jackson'

Prevention

When it happens

Trigger: Building an application that includes quarkus-spring-web (or spring-web resteasy-reactive variant) without any of quarkus-resteasy-jackson or quarkus-rest-jackson on the classpath.

Common situations: Projects migrated from Spring Boot where Jackson came transitively; apps using quarkus-rest (reactive) without the -jackson variant; manually trimmed dependency lists that removed the JSON extension.

Related errors


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