Summary
We're seeing an intermittent IllegalArgumentException
during HTTP response serialization using Spring Boot 3.4.2 on Kubernetes. The exact same image sometimes works perfectly, and other times fails with this error:
java.lang.IllegalArgumentException: getWriter() has already been called for this response
The exception occurs inside AbstractJackson2HttpMessageConverter.writeInternal(...)
, which is triggered via the standard message conversion flow when returning a response entity.
This does not appear to be a race condition in our own code, and we can't consistently reproduce it — but it happens often enough to be problematic (3–4 out of every 10 pod startups).
Stack Trace (Simplified)
The flow leading to the exception looks like this:
HttpEntityMethodProcessor.writeWithMessageConverters(...)→ AbstractMessageConverterMethodProcessor (switching converter)→ MappingJackson2HttpMessageConverter.write(...) [GENERIC]→ AbstractGenericHttpMessageConverter.write(...)→ AbstractJackson2HttpMessageConverter.writeInternal(...) ←💥 Exception thrown here
When the error does not occur, outputMessage.getBody()
returns an empty string. When the error does occur, it fails with the message above.
Details
- Spring Boot:
3.4.2
- Java:
21 (Temurin)
- Kubernetes: multiple environments DEV/TST/UAT were this problem all occurs opon
- Base image:
eclipse-temurin
- Frameworks used:
- Spring Security
<company>-spring-boot-starter
railway-event-spring-boot-starter
railway-mongo-spring-boot-starter
What We've Observed
- No suspicious code in our own initialization paths.
- No relevant
@PostConstruct
, Flyway, or Liquibase that could interfere. - Only one pod is deployed at a time.
- Pod restarts are sufficient to flip between failure/success.
- The image is identical across runs.
- The error only appears during response serialization.
Unfortunately, we can’t run the image locally — we debugged this remotely and verified the issue is inside Spring’s internal message converter flow.
Question
- Are there known conditions where Spring’s
HttpServletResponse
or Jackson-based converter may hit thisgetWriter()
conflict intermittently? - Could this be related to something in the servlet container initialization (Tomcat, etc.) or Kubernetes startup timing?
- Any tips to add guards or make this behavior more predictable?
Let me know what else we can share to help isolate the root cause.
Thanks!
Tried
Did a lot of searching..
Verified that the exact same Docker image is used across pod restarts (no code changes).
Remote-debugged the code and confirmed that the correct body is passed to the response, and the error happens deep in Spring’s message conversion layer.
Looked into timing, environment differences, or potential differences in request/response flow — nothing unusual.
Ensured that environment variables and secrets are consistently loaded — no missing values or nulls.
We also cannot reproduce the issue locally — only in Kubernetes — which makes this difficult to isolate.
Expected behavior
We expect the Spring application to return a valid HTTP response body without error, as it does in the majority of cases. Since the body is correctly constructed and the converter is selected appropriately, it should serialize and return the response without throwing an IllegalArgumentException.