The Content-Type header sent by your client is not recognized by the Spring Boot application’s message converters, preventing it from deserializing your request body.
Common Causes and Fixes
1. Incorrect Content-Type Header in Client Request
- Diagnosis: Inspect the
Content-Typeheader in the outgoing HTTP request from your client (e.g., using browser developer tools,curl -v, or a proxy like Charles). Common mistakes include typos, using the wrong MIME type (e.g.,application/jsoninstead ofapplication/xml), or forgetting it entirely. - Fix: Ensure the
Content-Typeheader exactly matches one of the supported types by yourHttpMessageConverterimplementations. For JSON, this is typicallyapplication/json.curl -X POST \ http://localhost:8080/api/resource \ -H 'Content-Type: application/json' \ -d '{"key": "value"}' - Why it works: Spring Boot uses the
Content-Typeheader to select the appropriateHttpMessageConverter(likeMappingJackson2HttpMessageConverterfor JSON) to deserialize the request body. If the header is missing or incorrect, no converter can be found.
2. Missing Jackson Dependency for JSON
- Diagnosis: If you’re expecting to send JSON but are getting this error, you might have forgotten to include the Jackson Databind dependency, which is essential for JSON processing in Spring Boot.
- Fix: Add the
jackson-databinddependency to yourpom.xml(Maven) orbuild.gradle(Gradle).- Maven:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> - Gradle:
implementation 'com.fasterxml.jackson.core:jackson-databind'
- Maven:
- Why it works: Spring Boot auto-configures Jackson’s
MappingJackson2HttpMessageConverterwhen this dependency is present, enabling it to handleapplication/jsonrequests.
3. Custom HttpMessageConverter Not Registered or Configured Incorrectly
- Diagnosis: If you’ve implemented a custom
HttpMessageConverter(e.g., for a specific binary format or a less common text format), verify that it’s properly registered with Spring and that itscanReadmethod correctly identifies theContent-Typeit handles. - Fix: Ensure your custom converter is registered as a Spring
@Beanor that it’s included in the list of converters managed byWebMvcConfigurer.
Make sure your@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(new MyCustomHttpMessageConverter()); } }MyCustomHttpMessageConverter’scanRead(Class<?> clazz, MediaType mediaType)method returnstruefor theMediaTypeyou are sending. - Why it works: Spring Boot’s MVC configuration needs to be aware of any custom converters you provide so it can consider them when matching
Content-Typeheaders.
4. Incorrect Accept Header vs. Content-Type Header
- Diagnosis: While
Content-Typedictates how the request body should be interpreted, theAcceptheader tells the server what response format the client expects. A mismatch here isn’t the direct cause of "Media Type Not Supported" for the request, but it can lead to confusion or subsequent errors if the server tries to match response types incorrectly. The error message specifically points to the incomingContent-Type. - Fix: Ensure your client sends a
Content-Typethat matches the data you are sending. TheAcceptheader should specify what you want in return (e.g.,Accept: application/json).curl -X POST \ http://localhost:8080/api/resource \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '{"key": "value"}' - Why it works: This separates the concerns of request body deserialization (
Content-Type) from response body serialization (Accept), ensuring both parts of the HTTP interaction are correctly handled.
5. Content-Type Mismatch with Controller @RequestMapping consumes Attribute
- Diagnosis: If your controller method has a
consumesattribute specified in its@RequestMappingor@PostMappingannotation, Spring requires the incomingContent-Typeto match one of the specified types. - Fix: Update the
consumesattribute to include theContent-Typeyour client is sending, or adjust your client’sContent-Typeheader to match theconsumesattribute.
If your client is sending@PostMapping(value = "/data", consumes = "application/vnd.mycompany.v1+json") public ResponseEntity<?> processData(@RequestBody MyObject data) { // ... }application/json, change theconsumesattribute to:@PostMapping(value = "/data", consumes = "application/json") public ResponseEntity<?> processData(@RequestBody MyObject data) { // ... } - Why it works: The
consumesattribute acts as a filter, ensuring that the controller method is only invoked for requests with a matchingContent-Type, preventing ambiguous routing and ensuring the correct deserialization logic is applied.
6. Spring Boot Version Compatibility Issues with Message Converters
- Diagnosis: In very rare cases, particularly with significant upgrades or when mixing custom configurations with older Spring Boot starters, there might be subtle incompatibilities in how message converters are auto-configured or registered.
- Fix: Ensure your Spring Boot version is up-to-date and that you are using the standard starters (
spring-boot-starter-web). If you have a customWebMvcConfigurerorWebMvcRegistrations, review its implementation for any deprecated methods or incorrect overrides that might interfere with default converter registration. - Why it works: Standard Spring Boot starters provide well-tested configurations for common message types. Deviations from this or outdated configurations can lead to unexpected behavior in the message conversion pipeline.
The next error you’ll likely encounter after resolving this is a HttpMessageNotReadableException if the request body itself is malformed according to the Content-Type (e.g., invalid JSON syntax).