Description

Spring Boot version: 3.4.4 Java version: 17 Maven version: 3.9.0

I have a Spring Boot app that: 1. extends the OncePerRequestFilter to add headers, namely Content-Type and X-Content-Type-Options to every response. 2. extends the ResponseEntityExceptionHandler to enable custom exception handling for the IllegalArgumentException. 3. uses Jetty instead of Tomcat.

When I upgraded from Spring Boot 3.4.3 to 3.4.4, I observed a null value for the charset encoding in the Content-Type response header when I try to access an endpoint/resource that doesn't exist. For the previous version 3.4.3, there was no charset in the first place. null is not recognized as a legal charset so a different Spring Boot REST client that calls this app fails with:

Caused by: org.springframework.util.InvalidMimeTypeException: Invalid mime type "application/problem+json;charset=null": unsupported charset 'null'

Reproduction

A minimal application that reproduces this error is attached as a demo.zip file with this issue: demo.zip Download it, extract it to your local machine, build the app (mvn -DskipTests clean package) and run it (java -jar target\demo-0.0.1-SNAPSHOT.jar)...

With Spring Boot 3.4.4:

>curl -v localhost:8080/repro
* Uses proxy env variable no_proxy == '127.0.0.1,localhost'
* Host localhost:8080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8080...
* Connected to localhost (::1) port 8080
> GET /repro HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.9.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 404 Not Found
< Date: Thu, 19 Jun 2025 18:51:06 GMT
< X-Content-Type-Options: nosniff
< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< Content-Type: application/problem+json;charset=null
< Transfer-Encoding: chunked
<
{"type":"about:blank","title":"Not Found","status":404,"detail":"No static resource repro.","instance":"/repro"}* Connection #0 to host localhost left intact

With Spring Boot 3.4.3:

>curl -v localhost:8080/repro
* Uses proxy env variable no_proxy == '127.0.0.1,localhost'
* Host localhost:8080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8080...
* Connected to localhost (::1) port 8080
> GET /repro HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.9.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 404 Not Found
< Date: Thu, 19 Jun 2025 18:52:40 GMT
< X-Content-Type-Options: nosniff
< Content-Type: application/json

< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< Transfer-Encoding: chunked
<
{"type":"about:blank","title":"Not Found","status":404,"detail":"No static resource repro.","instance":"/repro"}* Connection #0 to host localhost left intact

Notes

I tried various combinations to see what caused this behaviour in Spring Boot 3.4.4. Here are my findings:

Server Extends OncePerRequestFilter? Extends ResponseEntityExceptionHandler? Output
Jetty application/json;charset=null
application/json
application/problem+json
application/json
Tomcat application/json

✔: this class is present in the Spring Boot app ❌: this class is not present in the Spring Boot app ➖: doesn't matter whether or not this class is present in the Spring Boot app

Additionally, between Spring Boot 3.4.3 and 3.4.4, I noticed that Jetty was upgraded from 12.0.16 to 12.0.18 so I tried checking if the problem was with Jetty by using 3.4.4 as usual but manually setting the Jetty version to 12.0.16 via the jetty.version Maven property but I still got the same problem.