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
- Add the appropriate serializer extension, e.g. quarkus-rest-jackson or quarkus-rest-jackson-config / quarkus-resteasy-reactive-jackson for JSON entities
- Ensure the resource method's @Produces media type matches a writer available for the entity class (e.g. String handles text/plain)
- Register a custom MessageBodyWriter for the entity class via @Provider or ServerMessageBodyWriter
- 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
- Always include a JSON extension (quarkus-rest-jackson or quarkus-rest-jsonb) when returning POJOs
- Keep @Produces in sync with registered writers for the entity type
- Add a startup/integration test that calls each endpoint and asserts 200
- Write a custom MessageBodyWriter for any exotic domain types instead of returning raw objects
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
- Could not find MessageBodyWriter for
- Could not find MessageBodyWriter for
- Could not find MessageBodyWriter for
- Could not find MessageBodyWriter for
- Failed to serialize content of type
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/59206432094918aa.
Report an issue: GitHub.