When building REST APIs in Spring Boot, developers often rely on Spring’s powerful annotation-based request mapping to validate incoming HTTP headers automatically. Usually, when a required header like authToken or Protocol-Version is missing, the framework throws a MissingRequestHeaderException, which can be cleanly handled with a global @ExceptionHandler.
However, one header often behaves differently — the Content-Type.
The Problem: Content-Type Doesn’t Trigger MissingRequestHeaderException
You might define a @PostMapping endpoint like this:
@PostMapping("/{payment-product}")
public ResponseEntity<GenericResponse<Object>> createPayment(
@RequestHeader("authToken") String authToken,
@RequestHeader("Protocol-Version") String protocolVersion,
@RequestHeader("Content-Type") String contentType,
@RequestBody PaymentRequestBody paymentRequest) {
// ...
}
For most headers, missing values trigger a MissingRequestHeaderException, which can be caught and handled by an exception handler such as:
@ExceptionHandler({MissingRequestHeaderException.class, MissingPathVariableException.class})
public ResponseEntity<Object> handleBadRequest(Exception exception) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new GenericResponse<>()
.withStatus(HttpStatus.BAD_REQUEST)
.withMessage("Missing parameters in the header or path"));
}
But when the Content-Type header is not provided, the framework does not raise a MissingRequestHeaderException. Instead, Spring intercepts the request before it reaches your controller, resulting in no handler being executed.
Why Spring Treats Content-Type Differently
The Content-Type header is a special HTTP header that defines how Spring should parse the request body.
If it’s missing or set incorrectly, Spring’s message converter layer throws a different type of exception — often an HttpMediaTypeNotSupportedException or HttpMessageNotReadableException.
This happens before the controller method is invoked, which explains why your @ExceptionHandler(MissingRequestHeaderException.class) doesn’t catch it.
How to Return a 400 Error When Content-Type Is Missing
To ensure your API returns a consistent 400 Bad Request when Content-Type is missing, you can extend your global exception handling strategy.
Here’s how to update your controller advice:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler({
MissingRequestHeaderException.class,
MissingPathVariableException.class,
HttpMediaTypeNotSupportedException.class
})
public ResponseEntity<Object> handleBadRequest(Exception exception) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(new GenericResponse<>()
.withStatus(HttpStatus.BAD_REQUEST)
.withMessage("Bad request: missing or invalid headers"));
}
}
By adding HttpMediaTypeNotSupportedException, your application will now also handle cases where the client omits the Content-Type header or uses an unsupported media type such as text/plain instead of application/json.
Optional: Add a Custom Filter for Header Validation
If you want finer control and early validation before Spring parses the request, you can add a Servlet filter to inspect headers:
@Component
public class ContentTypeValidationFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String contentType = httpRequest.getHeader("Content-Type");
if (httpRequest.getMethod().equalsIgnoreCase("POST") && (contentType == null || contentType.isBlank())) {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.sendError(HttpStatus.BAD_REQUEST.value(), "Missing Content-Type header");
return;
}
chain.doFilter(request, response);
}
}
This ensures the API always rejects invalid requests consistently — even before they reach your controller.
Best Practices for Header Validation
- ✅ Always declare mandatory headers using
@RequestHeaderwithrequired = true(default). - ✅ Use a global
@ControllerAdviceto centralize error handling. - ✅ Include
HttpMediaTypeNotSupportedExceptionin your exception handling to catchContent-Typeissues. - ✅ Add integration tests to verify missing or malformed header responses.
- ✅ Document expected headers clearly in your API specification (e.g., with Swagger or OpenAPI).
Conclusion
Handling headers consistently in a Spring Boot REST API ensures predictable and professional behavior.
While authToken or Protocol-Version are caught by MissingRequestHeaderException, Content-Type requires special attention because of how Spring parses the request body.
By extending your @ControllerAdvice with HttpMediaTypeNotSupportedException or introducing a simple filter, you can ensure that every missing Content-Type header results in a clean, meaningful 400 Bad Request response — improving both security and API reliability.


