quarkusio/quarkus · error · WebApplicationException
HTTP 406 Not Acceptable (no acceptable MessageBodyWriter for
Error message
HTTP 406 Not Acceptable (no acceptable MessageBodyWriter for the requested media types)
What it means
When a resource method's writers are constrained to specific media types and ServerSerialisers.findWriterNoMediaType cannot select a writer matching the request's Accept header, it throws a WebApplicationException carrying an HTTP 406 Not Acceptable response that lists the media types the resource can produce.
Source
Thrown at independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ServerSerialisers.java:387
continue;
}
constrainedResultsForClass.add(writer);
}
MediaType selected = null;
for (ResourceWriter writer : constrainedResultsForClass) {
selected = writer.serverMediaType()
.negotiateProduces(requestContext.serverRequest().getRequestHeader(HttpHeaders.ACCEPT)).getKey();
if (selected != null) {
break;
}
}
if (selected == null) {
Set<MediaType> acceptable = new HashSet<>();
for (ResourceWriter i : constrainedResultsForClass) {
acceptable.addAll(i.mediaTypes());
}
throw new WebApplicationException(Response
.notAcceptable(Variant
.mediaTypes(
acceptable.toArray(new MediaType[0]))
.build())
.build());
}
if (selected.isWildcardType() || (selected.getType().equals("application") && selected.isWildcardSubtype())) {
selected = MediaType.APPLICATION_OCTET_STREAM_TYPE;
}
List<MessageBodyWriter<?>> finalResult = new ArrayList<>(constrainedResultsForClass.size());
for (ResourceWriter i : constrainedResultsForClass) {
// this part seems to be needed in order to pass com.sun.ts.tests.jaxrs.ee.resource.java2entity.JAXRSClient
if (i.mediaTypes().isEmpty()) {
finalResult.add(i.instance());
} else {
for (MediaType mt : i.mediaTypes()) {
if (mt.isCompatible(selected)) {
finalResult.add(i.instance());View on GitHub (pinned to e1c734241f)
Solutions
- Fix the client's Accept header to include a media type the endpoint produces (e.g. application/json).
- Broaden the endpoint's @Produces annotation if it should serve additional media types, and register the corresponding MessageBodyWriter.
- If content negotiation is meant to be flexible, use @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) with writers for each.
- Verify any reverse proxy is not stripping or rewriting the Accept header incorrectly.
Example fix
// before
@Produces(MediaType.APPLICATION_JSON)
public User get() { ... }
// client sends: Accept: application/xml
// after
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public User get() { ... } Defensive patterns
Strategy: try-catch
Validate before calling
// client-side: check Accept compatibility before calling
String produces = "application/json"; // from API docs/OpenAPI
String accept = myAcceptHeader;
if (!accept.contains(produces.split("/")[0])) {
log.warn("Accept header " + accept + " may cause HTTP 406 on this endpoint");
} Try / catch
try {
response = client.target(url).request(accept).get();
} catch (NotAcceptableException e) { // 406
log.warn("Endpoint cannot produce any requested media type; retrying with application/json");
response = client.target(url).request(MediaType.APPLICATION_JSON).get();
} Prevention
- Match client Accept headers to the endpoint's @Produces media types.
- Consult the OpenAPI document for supported response media types before coding clients.
- Avoid overly restrictive Accept headers (use */* or explicit supported types during debugging).
- Check proxy/gateway configurations that rewrite Accept headers.
When it happens
Trigger: A client sends an Accept header that intersects none of the @Produces media types of the matched resource method/class — e.g. requesting Accept: application/xml while the endpoint only produces application/json.
Common situations: API clients hard-coding Accept: application/xml against JSON-only endpoints; proxies/gateways adding or rewriting Accept headers; new content-type requirements added to clients after server-side @Produces was narrowed.
Understand the failure class
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Related errors
- Parameter: ${i} of the constructor of class '${resourceDotNa
- Parameter: ${i} of the constructor of class '${resourceDotNa
- Unsupported type '${jaxRSAnnotationOfParam.name()}' used as
- Unknown type '${type}' used as an annotation in constructor
- ${className} class reading failed
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/d4cecfdd6a14dc34.
Report an issue: GitHub.