spring-projects/spring-security · warning · NotAcceptableStatusException
Could not parse 'Accept' header
Error message
Could not parse 'Accept' header [<value>]: <ex.getMessage()>
What it means
MediaTypeServerWebExchangeMatcher resolves the request's Accept header to a list of MediaTypes to decide if the exchange matches. If the header contains a syntactically invalid media type, parsing throws InvalidMediaTypeException, which is converted to a 406 NotAcceptableStatusException with the offending header value and parse reason.
Solutions
- Fix the client to send a well-formed Accept header (e.g. 'application/json')
- Catch NotAcceptableStatusException on the server side and return a clean 406 response without internals
- Normalize/sanitize the Accept header in an upstream filter or gateway before the matcher runs
- If you control the matcher usage, wrap matching and fall back to a default media type
Example fix
// before curl -H 'Accept: application/json;' http://api/... // after curl -H 'Accept: application/json' http://api/...
Defensive patterns
Strategy: try-catch
Try / catch
try {
boolean matches = matcher.matches(exchange).block();
} catch (NotAcceptableStatusException ex) {
// malformed Accept header: treat as not-matching or respond 406
return matcherDoesNotMatch();
} Prevention
- Send explicit, simple Accept headers from clients (e.g. application/json)
- Avoid hand-building media-type strings with manual parameters/quality values
- Sanitize Accept headers at gateway/proxy layer for untrusted traffic
When it happens
Trigger: An incoming HTTP request whose Accept header cannot be parsed (malformed type/subtype, illegal characters, bad parameters) when the matcher's matches() is invoked during authorization or content negotiation.
Common situations: Browsers/proxies sending unusual or corrupted Accept headers; API clients hand-crafting Accept values like 'application/json;' with dangling parameters; automated tools sending Accept: */*;q= with malformed quality syntax.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- The request was rejected because the header
- The request was rejected because the header name
- A Bean named mvcHandlerMappingIntrospector of type…
- A Bean named mvcHandlerMappingIntrospector of type…
- A filter chain that matches any request
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/10e747ff22a420c6.
Report an issue: GitHub.
Appendix: source
Thrown at web/src/main/java/org/springframework/security/web/server/util/matcher/MediaTypeServerWebExchangeMatcher.java:147
* Set the {@link MediaType} to ignore from the {@link ContentNegotiationStrategy}.
* This is useful if for example, you want to match on
* {@link MediaType#APPLICATION_JSON} but want to ignore {@link MediaType#ALL}.
* @param ignoredMediaTypes the {@link MediaType}'s to ignore from the
* {@link ContentNegotiationStrategy}
*/
public void setIgnoredMediaTypes(Set<MediaType> ignoredMediaTypes) {
this.ignoredMediaTypes = ignoredMediaTypes;
}
private List<MediaType> resolveMediaTypes(ServerWebExchange exchange) throws NotAcceptableStatusException {
try {
List<MediaType> mediaTypes = exchange.getRequest().getHeaders().getAccept();
MimeTypeUtils.sortBySpecificity(mediaTypes);
return mediaTypes;
}
catch (InvalidMediaTypeException ex) {
String value = exchange.getRequest().getHeaders().getFirst("Accept");
throw new NotAcceptableStatusException(
"Could not parse 'Accept' header [" + value + "]: " + ex.getMessage());
}
}
@Override
public String toString() {
return "MediaTypeRequestMatcher [matchingMediaTypes=" + this.matchingMediaTypes + ", useEquals="
+ this.useEquals + ", ignoredMediaTypes=" + this.ignoredMediaTypes + "]";
}
}
View on GitHub (pinned to 96852e8860)