Skip to content

DispatcherServlet swallows HttpMediaTypeException during content negotiation in Spring Boot 3.5.9 #36300

@connect-ankit

Description

@connect-ankit

Description
During request mapping, when the Accept header contains a large number of media types (e.g., 50+), Spring MVC throws HttpMediaTypeException while parsing the header inside content negotiation.

Spring Boot version
3.5.9

Spring Framework version
6.2.15 (managed by Boot 3.5.9)

However, this exception is swallowed inside ProducesRequestCondition#getMatchingCondition() and null is returned instead of propagating the exception.

Because of this:

@ExceptionHandler(HttpMediaTypeNotAcceptableException.class) is never invoked
@ControllerAdvice cannot catch the error
request mapping fails silently
This makes it impossible to handle malformed or oversized Accept headers using standard MVC exception handling.

Observed behaviour

When calling an endpoint with many Accept values:

Accept: application/type1,application/type2, ... (60+)

Internally:

MediaType.parseMediaTypes()
  → throws HttpMediaTypeException

ProducesRequestCondition#getMatchingCondition()
  catch (HttpMediaTypeException)
  → returns null

Result:

handler mapping fails

controller not executed

exception never surfaces
Expected behaviour

One of the following:

Propagate HttpMediaTypeException to the MVC exception chain so @ExceptionHandler can handle it

Return 406/400 directly from DispatcherServlet

Currently, there is no way to handle large/malformed Accept headers inside MVC.

Reproduction

Request

curl -X GET http://localhost:8080/test \
$(for i in $(seq 1 60); do printf ' -H "Accept: application/type%d"' "$i"; done)

Result

handler not invoked
exception handler not invoked
Root cause (code reference)
Inside Spring Framework:
ProducesRequestCondition#getMatchingCondition

try {
    acceptedMediaTypes = this.getAcceptedMediaTypes(request);
}
catch (HttpMediaTypeException ex) {
    return null; **//The exception is swallowed here**
}

This swallowing prevents the exception from propagating to controller-level handlers.

Workaround

Add a OncePerRequestFilter to validate the Accept header before it reaches MVC:

@component

public class AcceptHeaderLimitFilter extends OncePerRequestFilter {
    private static final int MAX_ACCEPT_VALUES = 50;
    @Override
    protected void doFilterInternal(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        String accept = request.getHeader("Accept");
        if (accept != null) {
            int count = 1;
            for (int i = 0; i < accept.length(); i++) {
                if (accept.charAt(i) == ',') count++;
            }
            if (count > MAX_ACCEPT_VALUES) {
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                response.setContentType("application/json");
                response.getWriter().write(
                    "{\"error\":\"Bad Request\",\"error_description\":\"Too many Accept-header mime-types\"}"
                );
                return;
            }
        }
        chain.doFilter(request, response);
    }
}

Note: This workaround works but requires infrastructure-level filtering; ideally, MVC should allow handling this exception at the controller level.

Additional Notes

Behaviour became more visible after upgrading to Spring Boot 3.5.x (Spring Framework 6.2)

Is swallowing HttpMediaTypeException inside ProducesRequestCondition#getMatchingCondition() the intended design?

If yes, is there a recommended way to propagate it to @ExceptionHandler or customized the response without using a pre-filter?

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: webIssues in web modules (web, webmvc, webflux, websocket)status: declinedA suggestion or change that we don't feel we should currently apply

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions