quarkusio/quarkus · error · InternalServerErrorException

Could not find MessageBodyWriter for ${entity.getClass()}

Error message

Could not find MessageBodyWriter for ${entity.getClass()}

What it means

RESTEasy Reactive could not find a MessageBodyWriter capable of serializing the response entity for the requested media type. When the initial writer discovery fails (rediscoveryNeeded), the server re-scans registered serializers at write time and throws this InternalServerErrorException (HTTP 500) if none match. This means the runtime has no registered writer for the entity class + media type combination.

Source

Thrown at independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/WriterInterceptorContextImpl.java:55

        super(context, annotations, type, genericType, mediaType, serialisers);
        this.interceptors = interceptors;
        this.writer = writer;
        this.entity = entity;
        this.headers.putAll(headers);
    }

    @Override
    public void proceed() throws IOException, WebApplicationException {
        Response response = context.getResponse().get();
        // this is needed in order to avoid having the headers written out twice
        context.serverResponse().setPreCommitListener(null);
        if (index == interceptors.length) {
            MessageBodyWriter effectiveWriter = writer;
            if (rediscoveryNeeded) {
                List<MessageBodyWriter<?>> newWriters = serialisers.findWriters(null, entity.getClass(), mediaType,
                        RuntimeType.SERVER);
                if (newWriters.isEmpty()) {
                    throw new InternalServerErrorException("Could not find MessageBodyWriter for " + entity.getClass(),
                            Response.serverError().build());
                }
                effectiveWriter = newWriters.get(0);
            }
            context.setResult(Response.fromResponse(response).replaceAll(headers).build());
            ServerSerialisers.encodeResponseHeaders(context);
            // this must be done AFTER encoding the headers, otherwise the HTTP response gets all messed up
            effectiveWriter.writeTo(entity, type, genericType,
                    annotations, mediaType != null ? mediaType : context.getResponseMediaType(), response.getHeaders(),
                    context.getOrCreateOutputStream());
            context.getOutputStream().close();
            done = true;
        } else {
            interceptors[index++].aroundWriteTo(this);
            if (!done) {
                //TODO: how to handle
                context.setResult(Response.fromResponse(response).replaceAll(headers).build());
                ServerSerialisers.encodeResponseHeaders(context);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add the appropriate serializer extension, e.g. quarkus-rest-jackson or quarkus-rest-jackson-config / quarkus-resteasy-reactive-jackson for JSON entities
  2. Ensure the resource method's @Produces media type matches a writer available for the entity class (e.g. String handles text/plain)
  3. Register a custom MessageBodyWriter for the entity class via @Provider or ServerMessageBodyWriter
  4. If returning a generic/unknown type, convert it to a supported type (String, byte[], Map) before returning

Example fix

// before
@GET
@Produces(MediaType.APPLICATION_JSON)
public MyPojo get() { return new MyPojo(); } // fails if no JSON writer registered

// after (add dependency)
// <dependency>io.quarkus:quarkus-rest-jackson</dependency>
@GET
@Produces(MediaType.APPLICATION_JSON)
public MyPojo get() { return new MyPojo(); }
Defensive patterns

Strategy: try-catch

Validate before calling

// fail fast at build/startup
assert jakarta.ws.rs.ext.RuntimeDelegate.getInstance() != null;
// ensure a JSON mapper is on the classpath:
// Class.forName("com.fasterxml.jackson.databind.ObjectMapper")
Class<?> jsonMapper = null;
try { jsonMapper = Class.forName("com.fasterxml.jackson.databind.ObjectMapper"); } catch (ClassNotFoundException e) { throw new IllegalStateException("Add quarkus-rest-jackson to serialize JSON entities"); }

Type guard

boolean hasRegisteredWriter(Class<?> entity, MediaType mt) {
    return entity == String.class || entity == byte[].class
        || mt.isCompatible(MediaType.APPLICATION_JSON_TYPE) && jsonExtensionPresent;
}

Try / catch

try {
    return resource.call();
} catch (InternalServerErrorException e) {
    if (e.getMessage() != null && e.getMessage().contains("Could not find MessageBodyWriter")) {
        log.errorf("Entity type %s has no writer; add quarkus-rest-jackson or a custom MessageBodyWriter", e);
        return Response.status(500).entity("Serialization unsupported").build();
    }
    throw e;
}

Prevention

When it happens

Trigger: Returning a response entity whose class has no registered MessageBodyWriter for the requested @Produces media type; the rediscovery path in ServerSerialisers.findWriters(null, entity.getClass(), mediaType, RuntimeType.SERVER) returns an empty list in WriterInterceptorContextImpl.proceed.

Common situations: Returning a POJO without JSON support on the classpath (missing quarkus-rest-jackson/jsonb) with application/json; returning custom types with an @Produces like text/xml when no XML serializer is registered; dynamic media types negotiated to an unsupported format; returning objects from a ResourceMethod without @Produces causing strict writer lookup.

Related errors


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