title: Apache HttpClient timeout exception after server responds
body: <p>I use Apache HttpClient 4.1.2 to POST zipped binary data (serialized Java objects) to a server.</p>
  
  <p>Sometimes (20% of the time) the client will time out while receiving the response, <b>even after the server has responded correctly</b> and logged a "200" response in its own logging.</p>
  
  <p>The sequence of events is:</p>
  
  <ul>
  <li>client POSTs data to server (T0).</li>
  <li>server logs receipt of data (T2, i.e. T + 2 seconds).</li>
  <li>server processes data.</li>
  <li>server logs successful completion of processing (T45).</li>
  <li>server access log shows completed response going out with a "200" status (T46).</li>
  <li>client blocks reading response headers.</li>
  <li>client times out (T1800, i.e. 30 minutes after POSTing request, which is the standard timeout I use).</li>
  </ul>
  
  <p>The response body the server returns is a small, like five bytes or less, plain text string, e.g. "OK".</p>
  
  <p>What can be happening here?  I could understand timing out if the server hasn't responded; but the server has responded, and has logged a correct response, in a timely way, long before the client times out.  The client seems to be "trying" to read the response but blocks and eventually times out.</p>
  
  <p>The client is running on a Windows XP machine; the server is Ubuntu.  Both are running Java 6 (1.6.29 right now).</p>
  
  <p>I'm creating a fresh <code>DefaultHttpClient</code> object on each request, and shutting it down (and releasing other resources appropriately) after each request.</p>
  
  <p>The client consumes and disposes of the response entity body after the request successfully completes, but we haven't gotten to that point yet - the timeout is occurring in the context of the <code>httpclient.execute</code> (method) call.</p>
  
  <p>Stack trace:</p>
  
  <pre><code>java.net.SocketTimeoutException: Read timed out
      at java.net.SocketInputStream.socketRead0(Native Method)
      at java.net.SocketInputStream.read(Unknown Source)
      at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:149)
      at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:110)
      at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:264)
      at org.apache.http.impl.conn.LoggingSessionInputBuffer.readLine(LoggingSessionInputBuffer.java:115)
      at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:98)
      at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:252)
      at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:281)
      at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:247)
      at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:219)
      at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:298)
      at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
      at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:645)
      at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:464)
      at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
      at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
      at foo.StreamerClient.sendRequest(StreamerClient.java:312)
      at foo.StreamerClient.compressAndPostBinaryDataToFooServer(StreamerClient.java:287)
      at foo.StreamerClient.compressAndPostObjectsToFooServer(StreamerClient.java:238)
  </code></pre>
  
  <p>Here's the wire level logging from a successful request.  The only difference from the unsuccessful requests is that the unsuccessful ones stop after logging the binary data, and half an hour later pop up again and log the timeout.</p>
  
  <pre><code>[12-06 14:07:22.359][scheduler-3] D DefaultClientConnection   Sending request: POST /foo/bar HTTP/1.1 
  [12-06 14:07:22.359][scheduler-3] D wire                      &gt;&gt; "POST /foo/bar HTTP/1.1[\r][\n]" 
  [12-06 14:07:22.359][scheduler-3] D wire                      &gt;&gt; "Accept-Encoding: gzip,deflate[\r][\n]" 
  [12-06 14:07:22.359][scheduler-3] D wire                      &gt;&gt; "Content-Type: application/octet-stream[\r][\n]" 
  [12-06 14:07:22.359][scheduler-3] D wire                      &gt;&gt; "Content-Length: 401[\r][\n]" 
  [12-06 14:07:22.359][scheduler-3] D wire                      &gt;&gt; "Host: foo.com[\r][\n]" 
  [12-06 14:07:22.359][scheduler-3] D wire                      &gt;&gt; "Connection: Keep-Alive[\r][\n]" 
  [12-06 14:07:22.359][scheduler-3] D wire                      &gt;&gt; "User-Agent: Apache-HttpClient/4.1.2 (java 1.5)[\r][\n]" 
  [12-06 14:07:22.359][scheduler-3] D wire                      &gt;&gt; "Authorization: Basic fobar[\r][\n]" 
  [12-06 14:07:22.359][scheduler-3] D wire                      &gt;&gt; "[\r][\n]" 
  [12-06 14:07:22.359][scheduler-3] D wire                      &gt;&gt; "[several lines of binary data]" 
  [12-06 14:07:24.265][scheduler-3] D wire                      &lt;&lt; "HTTP/1.1 200 OK[\r][\n]" 
  [12-06 14:07:24.265][scheduler-3] D wire                      &lt;&lt; "Date: Tue, 06 Dec 2011 03:07:23 GMT[\r][\n]" 
  [12-06 14:07:24.265][scheduler-3] D wire                      &lt;&lt; "Content-Type: text/plain;charset=ISO-8859-1[\r][\n]" 
  [12-06 14:07:24.265][scheduler-3] D wire                      &lt;&lt; "Content-Length: 2[\r][\n]"
  [12-06 14:07:24.265][scheduler-3] D wire                      &lt;&lt; "Connection: close[\r][\n]"
  [12-06 14:07:24.265][scheduler-3] D wire                      &lt;&lt; "[\r][\n]" 
  </code></pre>
  
  <p>Thanks.</p>