{"record":{"id":"d4cecfdd6a14dc34","repo":"quarkusio/quarkus","slug":"http-406-not-acceptable-no-acceptable-messagebody","errorCode":null,"errorMessage":"HTTP 406 Not Acceptable (no acceptable MessageBodyWriter for the requested media types)","messagePattern":"HTTP 406 Not Acceptable \\(no acceptable MessageBodyWriter for the requested media types\\)","errorType":"http","errorClass":"WebApplicationException","httpStatus":406,"severity":"error","filePath":"independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ServerSerialisers.java","lineNumber":387,"sourceCode":"                continue;\n            }\n            constrainedResultsForClass.add(writer);\n        }\n        MediaType selected = null;\n        for (ResourceWriter writer : constrainedResultsForClass) {\n            selected = writer.serverMediaType()\n                    .negotiateProduces(requestContext.serverRequest().getRequestHeader(HttpHeaders.ACCEPT)).getKey();\n            if (selected != null) {\n                break;\n            }\n        }\n        if (selected == null) {\n            Set<MediaType> acceptable = new HashSet<>();\n            for (ResourceWriter i : constrainedResultsForClass) {\n                acceptable.addAll(i.mediaTypes());\n            }\n\n            throw new WebApplicationException(Response\n                    .notAcceptable(Variant\n                            .mediaTypes(\n                                    acceptable.toArray(new MediaType[0]))\n                            .build())\n                    .build());\n        }\n        if (selected.isWildcardType() || (selected.getType().equals(\"application\") && selected.isWildcardSubtype())) {\n            selected = MediaType.APPLICATION_OCTET_STREAM_TYPE;\n        }\n        List<MessageBodyWriter<?>> finalResult = new ArrayList<>(constrainedResultsForClass.size());\n        for (ResourceWriter i : constrainedResultsForClass) {\n            // this part seems to be needed in order to pass com.sun.ts.tests.jaxrs.ee.resource.java2entity.JAXRSClient\n            if (i.mediaTypes().isEmpty()) {\n                finalResult.add(i.instance());\n            } else {\n                for (MediaType mt : i.mediaTypes()) {\n                    if (mt.isCompatible(selected)) {\n                        finalResult.add(i.instance());","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ServerSerialisers.java#L369-L405","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n@Produces(MediaType.APPLICATION_JSON)\npublic User get() { ... }\n// client sends: Accept: application/xml\n// after\n@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})\npublic User get() { ... }","handlingStrategy":"try-catch","validationCode":"// client-side: check Accept compatibility before calling\nString produces = \"application/json\"; // from API docs/OpenAPI\nString accept = myAcceptHeader;\nif (!accept.contains(produces.split(\"/\")[0])) {\n    log.warn(\"Accept header \" + accept + \" may cause HTTP 406 on this endpoint\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    response = client.target(url).request(accept).get();\n} catch (NotAcceptableException e) { // 406\n    log.warn(\"Endpoint cannot produce any requested media type; retrying with application/json\");\n    response = client.target(url).request(MediaType.APPLICATION_JSON).get();\n}","preventionTips":["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."],"tags":["quarkus","resteasy-reactive","http-406","content-negotiation","http"],"backgroundTag":"http-406-not-acceptable","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}