reactor.netty.http.client.PrematureCloseException: Connection prematurely closed DURING response
mursilsayed opened this issue · comments
We are upgrading our Spring cloud gateway service from Spring Boot 2.7 to Spring boot 3.
Gateway service is using RetryGatewayFilter . We have an integration test to ensure that gateway retries http request when upstream returns 429. This integration tests starts failing when we upgraded to Spring Boot3. Investigating the issue revealed that retry filter is not working as we are receiving an error reactor.netty.http.client.PrematureCloseException: Connection prematurely closed DURING response
Partial Stack trace
2023-11-10T00:15:24.411+11:00 WARN 28121 --- [ctor-http-nio-3] r.netty.http.client.HttpClientConnect : [139692d6-1, L:/127.0.0.1:61154 ! R:localhost/127.0.0.1:61151] The connection observed an error
reactor.netty.http.client.PrematureCloseException: Connection prematurely closed DURING response
I created a sample application to reproduce the issue. testRoutingWithRetryFilter
represents the failing test case. It also creates TCP dumps from netty.
Expected Behavior
Retry filter should not throw PrematureCloseException when attempting to retry and the wiremock verification should confirm that it received 6 requests (1 +5 retries).
Actual Behavior
Wiremock only receives the first request and it sends back 429 in response. As soon as retry filter logic kicks in, Netty client starts throwing PrematureCloseException.
Steps to Reproduce
- Check out the code Retry filter.
- Run test by typing
./gradlew test
.testRoutingWithRetryFilter
should fail displaying the tcp dump and stack trace.
Your Environment
- org.springframework.boot -> 3.1.5
- Reactor version(s) used: spring-cloud-starter-gateway:4.0.7, spring-boot-starter-webflux:6.0.2
- Other relevant libraries versions (eg.
netty
, ...): - JVM version (
java -version
): 17 - OS and version (eg.
uname -a
): MacOS
@mursilsayed With the provided example I cannot reproduce the exception. I also do not see retry attempts. As per Spring Cloud Gateway by default only GET requests that return 500 ISE will be retried.
In your configuration I don't see configuration for 429 response code.
https://github.com/mursilsayed/springcloudgateway-retryfilter/blob/5a39bb541be7f006cf830a2cee265041167fa008/src/main/kotlin/com/example/gatewayfilter/RoutesConfiguration.kt#L26
https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/gatewayfilter-factories/retry-factory.html
@violetagg Thank you for looking into this issue and for providing a prompt response.
In your configuration I don't see configuration for 429 response code.
I think I now better understand why the retry filter was not working in our application. I was trying to reproduce a similar issue in the sample application but I now realise that it is not raising the same exception. It is just displaying the same message in the error log.
Please go ahead and close this issue.