Have you tried calling a HTTP api using Netty client? probably you would have indirectly using it if you are using the SpringBoot webclient to make such API calls, cause the WebClient internally uses netty's HttpClient for making the calls in non blocking way.
The client designed to keep the connection in a connection pool in order to reuse it for the next time, when a request is initiated for the same server. However, rarely this client might throw reactor.netty.http.client.PrematureCloseException: Connection prematurely closed BEFORE response exception.
This often probably means, that the connection is closed by the destination server, while a request sending is initiated using this connection by the netty's HttpClient.
Suppose the connection is closed by the destination server, while the connection is idle in the netty's connection pool, then this exception will not occur if the destination server property send its signal to close the connection. In such case netty will disregard that idle connection and will initiate new one when next time new request comes for the same destination server.
Therefore, this exception is difficult to recreate and occur rarely.
Possible scenario
Following is one possible scenario that this exception can be observed occasionally.
Assume you have a Http API deployed using the tomcat based spring boot server and you started to make API call using netty's HttpClient for every 60 seconds.
Then rarely you might observe few PrematureCloseException over time. This is because the tomcat, by default, keeps the connection idle for 60 seconds and when while netty try to use that connection, if tomcat mark it for close, due to the 60 seconds timeout, then call fails with PrematureCloseException.
Above mentioned problem can be fixed if the tomcat connection idle timeout set to more than 60 seconds or netty's http connection idle timeout set to less than 60 seconds.
How to set connection idle timeout for Tomcat
Mostly keepAliveTimeout setting, which set to the value of connectionTimeout by default, mistakenly taken as connection idle timeout setting to be adjusted. However, it has nothing to do with keeping the connection idle after serving a request.
keepAliveTimeout used to wait for another read from the same request, before concluding it as completed.
Once response sent, and client completes the request, then the tomcat connection left with OPEN_READ status, which means it is ready to start receiving new request, in that state, it uses connectionTimeout to decided whether it should idle the connection further or close the connection.
Therefore tomcat connectionTimeout is the one that should be changed, if you want to change how long a connection should be kept idle.
Also note that, if the connection is reused by tomcat(if got a new request from same client within connectionTimeout), then if a TLS handshake is already performed, it will be skipped next time removing the overhead of TLS handshake.
How to set connection idle timeout for Netty client
From netty's pool perspective, connection can be set to expire after being idle using the property maxIdleTimeout.
With that, it should be possible to handle the PrematureCloseException from netty's HttpClient.