{"record":{"id":"56c57a6683c58ee0","repo":"quarkusio/quarkus","slug":"the-content-type-header-value-did-not-match-the-va","errorCode":null,"errorMessage":"The content-type header value did not match the value in @Consumes","messagePattern":"The content-type header value did not match the value in @Consumes","errorType":"http","errorClass":"NotSupportedException","httpStatus":415,"severity":"error","filePath":"independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/HandlerMediaTypeUtil.java","lineNumber":36,"sourceCode":"import org.jboss.resteasy.reactive.server.mapping.RuntimeResource;\n\nclass HandlerMediaTypeUtil {\n\n    private static final String INVALID_ACCEPT_HEADER_MESSAGE = \"The accept header value did not match the value in @Produces\";\n    private static final String MALFORMED_ACCEPT_HEADER_MESSAGE = \"The accept header value did not correspond to a valid media type\";\n\n    // according to the spec we need to return HTTP 415 when content-type header doesn't match what is specified in @Consumes\n    // HttpMethod being null means this is a sub resource locator method. The handler chain of the sub resource has to match the content-type header\n    static void validateConsumes(RequestMapper.RequestMatch<RuntimeResource> target,\n            ResteasyReactiveRequestContext requestContext) {\n        if (target.value.getHttpMethod() != null && !target.value.getConsumes().isEmpty()) {\n            String contentType = (String) requestContext.getHeader(HttpHeaders.CONTENT_TYPE, true);\n            if (contentType != null) {\n                try {\n                    if (MediaTypeHelper.getFirstMatch(\n                            target.value.getConsumes(),\n                            Collections.singletonList(MediaTypeHelper.valueOf(contentType))) == null) {\n                        throw new NotSupportedException(\"The content-type header value did not match the value in @Consumes\");\n                    }\n                } catch (IllegalArgumentException e) {\n                    throw new NotSupportedException(\"The content-type header value did not correspond to a valid media type\");\n                }\n            }\n        }\n    }\n\n    // according to the spec we need to return HTTP 406 when Accept header doesn't match what is specified in @Produces.\n    // A fully unparseable Accept header is a client syntax error and returns HTTP 400 instead.\n    // HttpMethod being null means this is a sub resource locator method. The handler chain of the sub resource has to match the accept header\n    static void validateProduces(RequestMapper.RequestMatch<RuntimeResource> target,\n            ResteasyReactiveRequestContext requestContext) {\n        if (target.value.getHttpMethod() != null && target.value.getProduces() != null) {\n            // there could potentially be multiple Accept headers and we need to response with 406\n            // if none match the method's @Produces\n            List<String> accepts = (List<String>) requestContext.getHeader(HttpHeaders.ACCEPT, false);\n            if (!accepts.isEmpty()) {","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/HandlerMediaTypeUtil.java#L18-L54","documentation":"RESTEasy Reactive throws this NotSupportedException (HTTP 415) when the request's Content-Type header cannot be matched against the @Consumes media types declared on the target resource method. The library parses the header via MediaTypeHelper.valueOf and checks compatibility with the method's consumed types using getFirstMatch; if no match exists, it rejects the request per the JAX-RS spec. This happens in validateConsumes during request routing, before the resource method is invoked.","triggerScenarios":"A request is routed to a resource method with a non-empty @Consumes declaration, the Content-Type header is present, MediaTypeHelper.getFirstMatch(target.value.getConsumes(), [parsed content-type]) returns null — e.g. sending Content-Type: text/plain to a method annotated @Consumes(MediaType.APPLICATION_JSON).","commonSituations":"Clients posting form data (application/x-www-form-urlencoded) to JSON-only endpoints; frontends sending application/json but the endpoint declared text/plain or vice versa; copying endpoint code and forgetting to update @Consumes; API clients defaulting to text/xml or missing charset variants.","solutions":["Set the client request's Content-Type header to one of the media types in the endpoint's @Consumes annotation.","Widen or add media types on the server, e.g. change @Consumes(MediaType.APPLICATION_JSON) to @Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN}).","Remove the restrictive @Consumes annotation entirely to accept any content type (wildcard)."],"exampleFix":"// before\n@POST\n@Consumes(MediaType.APPLICATION_JSON)\npublic String create(Form form) { ... }\n// after\n@POST\n@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED})\npublic String create(Form form) { ... }","handlingStrategy":"validation","validationCode":"// client-side, before sending\nString contentType = \"application/json\";\nif (!contentType.matches(\"[\\w!#$&^_.+-]+/[\\w!#$&^_.+-]+.*\")) {\n    throw new IllegalArgumentException(\"Invalid Content-Type: \" + contentType);\n}\n// ensure it matches the endpoint's declared @Consumes","typeGuard":null,"tryCatchPattern":"try {\n    Response r = client.post(entity);\n} catch (NotSupportedException | ProcessingException e) {\n    // check response status 415 and log the Content-Type sent\n}","preventionTips":["Always set Content-Type explicitly on requests with bodies.","Keep @Consumes values in sync with what clients actually send.","Cover each media-type variant with an integration test."],"tags":["rest","http-415","content-type","jaxrs"],"backgroundTag":"unsupported-media-type","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}