title: PrematureCloseException: Connection prematurely closed
body: <p>im using Web-flux/Reactive and Webclient, running it on tomcat and spring-boot.</p>
  
  <p>Everything works fine. I read a lot about it. The problem seems to be that whenever you use webclient, you have to return or use the response, otherwise it will close the connection and you didn't consume it yet, and you will see a lot  of log messages saying that <code>the connection close prematurely</code>, if i had a scenario where a 404 status code is a error i could just use <code>OnStatus</code> and throw an exception, but my scenario is: when the upstream service returns a 404, i have to return manually a mono empty. so i don't use the response from web client request, i just use ClientResponse from .exchange() to check the status and handle it. My initial problem is the log messages, because is just "garbage", you don't want see a lot of it on your log messages. I've read somewhere that if it happens the connection cant be re-used as well, so it sounds really bad, but i don't know... and i just have this message when is not found, if the response is 200 it returns the object and log messages is not printed.</p>
  
  <p>I tried to use 
  clientResponse.BodyToMono(Void.Class)
  but it doesn't work either.
  the log messages keeping apearing</p>
  
  <pre><code> @Bean
    public WebClient webClient(
        @Value("${http.client.connection-timeout-millis}") final int connectionTimeoutMillis,
        @Value("${http.client.socket-timeout-millis}") final int socketTimeoutMillis,
        @Value("${http.client.wire-tap-enabled}") final boolean wireTapEnabled,
        final ObjectMapper objectMapper) {
  
      Consumer&lt;Connection&gt; doOnConnectedConsumer = connection -&gt;
          connection
              .addHandler(new ReadTimeoutHandler(socketTimeoutMillis, MILLISECONDS))
              .addHandler(new WriteTimeoutHandler(connectionTimeoutMillis, MILLISECONDS));
  
      TcpClient tcpClient = TcpClient.newConnection()
          .wiretap(wireTapEnabled)
          .option(CONNECT_TIMEOUT_MILLIS, connectionTimeoutMillis)
          .doOnConnected(doOnConnectedConsumer);
  
      return WebClient.builder()
          .clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient).compress(true)))
          .exchangeStrategies(customExchangeStrategies(objectMapper))
          .build();
    } 
  
  // ..........
  
      MultiValueMap&lt;String, String&gt; params = getParams(t1, t2);
  
      return webClient.get()
          .uri(HttpUtils.buildUrl(serviceUrl, params, name))
          .exchange()
          .flatMap(this::handleClientResponse)
          .onErrorMap(Exception.class, ex -&gt; handleUnexpectedEx(ex, name, params));
    }
  </code></pre>
  
  <p>log entries</p>
  
  <pre><code>2019-07-08 11:56:51.972  WARN [-,,,] 1504 --- [ctor-http-nio-3] reactor.netty.channel.FluxReceive        : [id: 0x66c8568c, L:/127.0.0.1:62319 ! R:localhost/127.0.0.1:8990] An exception has been observed post termination
  
  reactor.netty.http.client.PrematureCloseException: Connection prematurely closed DURING response
  
  2019-07-08 11:56:52.013 DEBUG [-,,,] 1504 --- [ctor-http-nio-2] reactor.netty.ReactorNetty               : [id: 0xf50bdf8d, L:/127.0.0.1:62324 ! R:localhost/127.0.0.1:8990] Non Removed handler: ReadTimeoutHandler, context: ChannelHandlerContext(ReadTimeoutHandler, [id: 0xf50bdf8d, L:/127.0.0.1:62324 ! R:localhost/127.0.0.1:8990]), pipeline: DefaultChannelPipeline{(reactor.left.httpCodec = io.netty.handler.codec.http.HttpClientCodec), (reactor.left.decompressor = io.netty.handler.codec.http.HttpContentDecompressor), (WriteTimeoutHandler = io.netty.handler.timeout.WriteTimeoutHandler), (ReadTimeoutHandler = io.netty.handler.timeout.ReadTimeoutHandler), (reactor.right.reactiveBridge = reactor.netty.channel.ChannelOperationsHandler)}
  2019-07-08 11:56:52.014 DEBUG [-,,,] 1504 --- [ctor-http-nio-2] reactor.netty.ReactorNetty               : [id: 0xf50bdf8d, L:/127.0.0.1:62324 ! R:localhost/127.0.0.1:8990] Non Removed handler: WriteTimeoutHandler, context: ChannelHandlerContext(WriteTimeoutHandler, [id: 0xf50bdf8d, L:/127.0.0.1:62324 ! R:localhost/127.0.0.1:8990]), pipeline: DefaultChannelPipeline{(reactor.left.httpCodec = io.netty.handler.codec.http.HttpClientCodec), (reactor.left.decompressor = io.netty.handler.codec.http.HttpContentDecompressor), (WriteTimeoutHandler = io.netty.handler.timeout.WriteTimeoutHandler), (ReadTimeoutHandler = io.netty.handler.timeout.ReadTimeoutHandler), (reactor.right.reactiveBridge = reactor.netty.channel.ChannelOperationsHandler)}
  2019-07-08 11:56:52.014 DEBUG [-,,,] 1504 --- [ctor-http-nio-2] r.netty.resources.NewConnectionProvider  : [id: 0xf50bdf8d, L:/127.0.0.1:62324 ! R:localhost/127.0.0.1:8990] onStateChange([response_incomplete], GET{uri=/service/TWFDHF?T1=1.0.0&amp;T2=1, connection=SimpleConnection{channel=[id: 0xf50bdf8d, L:/127.0.0.1:62324 ! R:localhost/127.0.0.1:8990]}})
  2019-07-08 11:56:52.014  WARN [-,,,] 1504 --- [ctor-http-nio-2] reactor.netty.channel.FluxReceive        : [id: 0xf50bdf8d, L:/127.0.0.1:62324 ! R:localhost/127.0.0.1:8990] An exception has been observed post termination
  </code></pre>
  
  <p>log entries with wiretap enabled</p>
  
  <pre><code>2019-07-10 14:51:19.295 DEBUG [-,,,] 2940 --- [ctor-http-nio-2] reactor.netty.tcp.TcpClient              : [id: 0x677da0d4, L:/127.0.0.1:62385 ! R:localhost/127.0.0.1:8990] UNREGISTERED
  2019-07-10 14:51:19.541 DEBUG [-,,,] 2940 --- [ctor-http-nio-4] reactor.netty.tcp.TcpClient              : [id: 0xa7f41d1e, L:/127.0.0.1:62384 - R:localhost/127.0.0.1:8990] CLOSE
  2019-07-10 14:51:19.542 DEBUG [-,,,] 2940 --- [ctor-http-nio-4] r.n.resources.PooledConnectionProvider   : [id: 0xa7f41d1e, L:/127.0.0.1:62384 ! R:localhost/127.0.0.1:8990] Channel cleaned, now 0 active connections and 9 inactive connections
  2019-07-10 14:51:19.542 DEBUG [-,,,] 2940 --- [ctor-http-nio-4] r.n.resources.PooledConnectionProvider   : [id: 0xa7f41d1e, L:/127.0.0.1:62384 ! R:localhost/127.0.0.1:8990] Channel closed, now 0 active connections and 8 inactive connections
  2019-07-10 14:51:19.542 DEBUG [-,,,] 2940 --- [ctor-http-nio-4] reactor.netty.ReactorNetty               : [id: 0xa7f41d1e, L:/127.0.0.1:62384 ! R:localhost/127.0.0.1:8990] Non Removed handler: ReadTimeoutHandler, context: ChannelHandlerContext(ReadTimeoutHandler, [id: 0xa7f41d1e, L:/127.0.0.1:62384 ! R:localhost/127.0.0.1:8990]), pipeline: DefaultChannelPipeline{(reactor.left.loggingHandler = io.netty.handler.logging.LoggingHandler), (reactor.left.httpCodec = io.netty.handler.codec.http.HttpClientCodec), (WriteTimeoutHandler = io.netty.handler.timeout.WriteTimeoutHandler), (ReadTimeoutHandler = io.netty.handler.timeout.ReadTimeoutHandler), (reactor.right.reactiveBridge = reactor.netty.channel.ChannelOperationsHandler)}
  2019-07-10 14:51:19.543 DEBUG [-,,,] 2940 --- [ctor-http-nio-4] reactor.netty.ReactorNetty               : [id: 0xa7f41d1e, L:/127.0.0.1:62384 ! R:localhost/127.0.0.1:8990] Non Removed handler: WriteTimeoutHandler, context: ChannelHandlerContext(WriteTimeoutHandler, [id: 0xa7f41d1e, L:/127.0.0.1:62384 ! R:localhost/127.0.0.1:8990]), pipeline: DefaultChannelPipeline{(reactor.left.loggingHandler = io.netty.handler.logging.LoggingHandler), (reactor.left.httpCodec = io.netty.handler.codec.http.HttpClientCodec), (WriteTimeoutHandler = io.netty.handler.timeout.WriteTimeoutHandler), (ReadTimeoutHandler = io.netty.handler.timeout.ReadTimeoutHandler), (reactor.right.reactiveBridge = reactor.netty.channel.ChannelOperationsHandler)}
  2019-07-10 14:51:19.543 DEBUG [-,,,] 2940 --- [ctor-http-nio-4] reactor.netty.tcp.TcpClient              : [id: 0xa7f41d1e, L:/127.0.0.1:62384 ! R:localhost/127.0.0.1:8990] INACTIVE
  2019-07-10 14:51:19.544 DEBUG [-,,,] 2940 --- [ctor-http-nio-4] r.n.resources.PooledConnectionProvider   : [id: 0xa7f41d1e, L:/127.0.0.1:62384 ! R:localhost/127.0.0.1:8990] onStateChange(GET{uri=/dataviews/TWN_EMPLBENINFO_FIXED?version=1.0.0&amp;sequence=1, connection=PooledConnection{channel=[id: 0xa7f41d1e, L:/127.0.0.1:62384 ! R:localhost/127.0.0.1:8990]}}, [response_incomplete])
  2019-07-10 14:51:19.544  WARN [-,,,] 2940 --- [ctor-http-nio-4] reactor.netty.channel.FluxReceive        : [id: 0xa7f41d1e, L:/127.0.0.1:62384 ! R:localhost/127.0.0.1:8990] An exception has been observed post termination
  </code></pre>
  
  <p>and my handler</p>
  
  <pre><code>protected Mono handleClientResponseError(final ClientResponse clientResponse) {
      clientResponse.bodyToMono(Void.class);
      Mono&lt;ErrorResponse&gt; errorResponse = clientResponse.body(BodyExtractors.toMono(ErrorResponse.class));
  
      return errorResponse.flatMap(err -&gt; {
        log.debug("Received HttpStatusCodeException when calling {} Registry: {}", getGatewayName(),
            err.getErrorEnvelope().getMessage());
  
        return Mono.error(new UpStreamServiceHttpException(err, clientResponse.rawStatusCode()));
      }).switchIfEmpty(Mono.error(() -&gt; {
        log.debug("Received HttpStatusCodeException when calling {} Registry: {}", getGatewayName());
  
        return new UpStreamServiceHttpException("Bad Gateway", clientResponse.rawStatusCode());
      }));
    }
  </code></pre>
  
  <p>I tried already use <code>clientResponse.bodyToMono(Void.class);</code> to complete the response, but it still doesnt work, i need a way to finish the response from web-client, and then be able to re-use the connection pool and get rid of those log messages</p>
  
  <p>i've created an issue on github, but it was closed, so im creating this question here. <a href="https://github.com/spring-projects/spring-framework/issues/23249" rel="noreferrer">https://github.com/spring-projects/spring-framework/issues/23249</a></p>