Repository navigation
Post Request with springboot4 Container hangs #1598
Description
I have a simple example application which uses AWS Serverless Java Container for Spring Boot 4 to store and retrieve a product from DynamoDB. You can deploy it with AWS SAM.
It works, if I use my own handler implementation for the PostProductFunction (which creates a new product, see template.yaml) like this:
PostProductFunction:
Type: AWS::Serverless::Function
Properties:
Handler: software.amazonaws.example.product.handler.StreamLambdaHandler::handleRequest
If I switch the handler to use
Handler: com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler
and activate a required MAIN_CLASS environment variable in the Globals Function section of the SAM template like this:
Globals:
Function:
.....
Environment:
Variables:
MAIN_CLASS: software.amazonaws.Application
REGION: !Sub ${AWS::Region}
JAVA_TOOL_OPTIONS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
PRODUCT_TABLE_NAME: !Ref ProductsTable
The POST request sent from the API Gateway with Content-Type:application/json as a HTTP Header and JSON payload { "id": 1, "name": "Print 10x13", "price": 15 } as a HTTP body runs into the 30 second timeout of the API Gateway and Lambda function even if I clearly see in the Lambda logs, that the request is executed, which means that ProductController createProduct method is sucessfully finished within a few seconds (and the product is created in the DynamoDB). I don't have any control what's happening outside of the Controller method when using the SpringDelegatingLambdaContainerHandler as a handler.
If I switch from POST to PUT in the SAM template and ProductController the behavior is the same (it hangs with the com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler handler).
I don't have such a problem with the GET request (for example GetProductByID) which finishes successfully in time.
Please help me investigate why the problem arise? Maybe I'm doing something wrong.
ADDED : I found out how to make it work. It didn't work when the createProduct method of ProductController returned void and didn't have produces mime type. Now I changed both (returning String and defined text/plain as produces mime type) and it works with com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler handler as well. Still it worked with returning void and not having produces mime type for POST/PUT with AWS Serverless Java Spring Boot 3 Container and Spring Boot 3 (I cheked my working examples). The most important thing: it should work the same way regardless whether I define my own StreamHandler , which works fine with return void and without produces mime type for POST/PUT or re-use the existing com.amazonaws.serverless.proxy.spring.SpringDelegatingLambdaContainerHandler handler.
And, of course, I'd at least expect exception, instead of hanging and runnung into timeout. So please review the issue and fix it.
Activity
kosmakdm commentedon Mar 3, 2026
Hi! I have the same issue when I migrate to springboot4. I've done some investigation and here are my findings.
Root Cause
Both
SpringDelegatingLambdaContainerHandler.handleRequest()andAwsSpringWebCustomRuntimeEventLoop.eventLoop()unconditionally callhttpServletRequest.startAsync()before delegating toAwsSpringHttpProcessingUtils.processRequest(). Thespringboot3module does NOT make this call.Calling
startAsync()sets the request's dispatcher type toDispatcherType.ASYNC. After the servlet chain completes, there is a safety-net flush:With dispatcher type
ASYNC, this safety net is skipped. The response'sflushBuffer()is the only place that callswritersCountDownLatch.countDown(). For controllers that return a body, theHttpMessageConverterflushes the output stream during serialization, so the latch counts down regardless. But for "void-returning controllers" no converter runs, no flush happens, andlatch.await(15, TimeUnit.MINUTES)blocks until timeout.Why it works with springboot3: the
springboot3module never callsstartAsync(), so the safety-net flush always fires.Why GET works but POST with void return doesn't: GET endpoints typically return a body, which triggers the flush through the message converter path.
Fix: Remove the unconditional
startAsync()calls from the springboot4 module. I've submitted a PR with this fix and a test: prtoinux commentedon Mar 9, 2026
Hello, another issue, I was trying oauth2 authentication with :
the BearerTokenAuthenticationFilter did not work because it extends OncePerRequestFilter, and OncePerRequestFilter skips dispatch if DispatcherType is ASYNC :
@kosmakdm I confirm that #1600 solves this issue too.
Thanks !
fraser148 commentedon Mar 9, 2026
Also running into this, would love to see this merged? @tobixlea
tobixlea commentedon Mar 16, 2026
fix has been merged and new version release has been published to maven central
GitHub release entry: https://github.com/aws/serverless-java-container/releases
Maven repo: https://repo1.maven.org/maven2/com/amazonaws/serverless/
Note: It may take up to a few hours for the artifact to be published and available on Maven Central
tobixlea commentedon Mar 16, 2026
Keeping thread open in order to verify fix is working properly for users before closing
toinux commentedon Mar 17, 2026
So far it works for me !
tobixlea commentedon Mar 20, 2026
Closing as fix has been merged and no further issue has been brought forward.