httpclient exception "org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection"

JavaExceptionHttpclient

Java Problem Overview


I am trying to send request to my server, with following code. it failed at 3rd request, always.

import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

public class HttpClientTest {
	private HttpClient client;

	public HttpClientTest() {
		HttpParams params = new BasicHttpParams();
		params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 15000);  
		params.setParameter(CoreConnectionPNames.SO_TIMEOUT, 15000);
		
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
		HttpProtocolParams.setContentCharset(params, "utf-8");
		HttpProtocolParams.setUseExpectContinue(params, true);
		ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager();
		cm.setMaxTotal(100);
		client = new DefaultHttpClient(cm, params);
		
		while (true) {
			HttpPost mPost = new HttpPost("http://myip/myservice");
			
			JSONObject json = new JSONObject();
			try {
				json.put("serialNumber", "abcd");
			} catch (JSONException e1) {
				e1.printStackTrace();
			}
			StringEntity s = null;
			try {
				s = new StringEntity(json.toString());
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}   			
			s.setContentEncoding("UTF-8");
			s.setContentType("application/json");
			mPost.setEntity(s);

			JSONObject response = null;

			System.out.println("HttpClientTest ---> send post");
			HttpResponse mHttpResponse;
			try {
				mHttpResponse = client.execute(mPost);
				System.out.println("HttpClientTest  ---> get response");
				if(mHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
	                HttpEntity entity = mHttpResponse.getEntity(); 
					ContentType contentType = ContentType.getOrDefault(entity);
	                Charset charset = contentType.getCharset();
	                response = new JSONObject(new JSONTokener(new InputStreamReader(entity.getContent(), charset)));
	                
	                System.out.println("HttpClientTest ---> get result:" + response.toString());
				} else {
					mPost.abort();
					break;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		HttpClientTest t = new HttpClientTest();
	}
}

the exception as following:

org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection
	at org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getEntryBlocking(ConnPoolByRoute.java:417)
	at org.apache.http.impl.conn.tsccm.ConnPoolByRoute$1.getPoolEntry(ConnPoolByRoute.java:300)
	at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1.getConnection(ThreadSafeClientConnManager.java:224)
	at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:401)
	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
	at com.i360r.client.takeaway.network.HttpClientTest.<init>(HttpClientTest.java:68)
	at com.i360r.client.takeaway.network.HttpClientTest.main(HttpClientTest.java:88)

Java Solutions


Solution 1 - Java

I had the same problem and I found the fix. This timeout is because of a connection leak. In my case, I'm using httpDelete method and not consuming the response. Instead, I'm checking the status of the response.

The fix is, the response entity needs to be consumed. In order to ensure the proper release of system resources, one must close the content stream associated with the entity.

So I used EntityUtils.consumeQuietly(response.getEntity()); which ensures that the entity content is fully consumed and the content stream, if exists, is closed.

Solution 2 - Java

I have fixed it! add mPost.releaseConnection() in finally blocks.

 try {
 } catch (Exception e) {
 } finally {
  mPost.releaseConnection();
 }

DO update package org.apache.httpcomponents to 4.2.1

Solution 3 - Java

Just put the line where you are getting your response inside try-with-resources and use CloseableHttpResponse instead of HttpResponse like this:

try(final CloseableHttpResponse mHttpResponse = client.execute(mPost);)
{
 System.out.println("HttpClientTest  ---> get response");
 ....remainder code

The mHttpResponse object will be auto consumed and closed for you

Hope this helps!

Solution 4 - Java

Use a CloseableHttpClient instead of HttpClient. You'll get a CloseableHttpResponse instead of a HttpResponse which support close(). So, when you are done with the response, just close it, no need to close the connection.

CloseableHttpResponse response = closableHttpClient.execute(httpPost, context);

...do what you need to do with it:

response.close();

Solution 5 - Java

This can also happen if you're using ApacheHttpClient with DropWizard 0.6.2, which behind the scenes creates an MultiThreadedHttpConnectionManager with a default configuration - and that default configuration only allowed 2 concurrent http connections at a time more info here.

So with this configuration, if your server is getting swamped and making requests to the same host all the time, you'll have max 2 connections allowed running at a time!

Solution 6 - Java

We faced the same issue, and we were limited because the connection from pool has initial value of DefaultMaxPerRoute as 2. Ours was an API which would fire different calls with same URI but, different body. Once we set it explicitly to higher value like this

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
    cm.setMaxTotal(40);
    cm.setDefaultMaxPerRoute(20);

we were able to resolve it.

Solution 7 - Java

We were hitting this error when writing and reading parquets via spark. The exact error was:
com.amazonaws.SdkClientException: Unable to execute HTTP request: Timeout waiting for connection from pool

We finally figured out that this was related to the upgrade of Hadoop to version 3.1.3

Seems that in this new version the Hadoop, the property name been changed from:
fs.s3a.connection.maximum
to:
spark.hadoop.fs.s3a.connection.maximum

Renaming the property in our spark configuration, set us back on track.

Solution 8 - Java

I hit the same error. It turns out that I needed to close the response.

CloseableHttpResponse response = null;
try {
       response = ##some code
} catch(Exception e) {
  if (response != null) {
      response.close();
  }
}

Solution 9 - Java

As Rama said, this could be a sign of a connection leak.

releaseConnection() could help resolve this issue but you might need to find out the root cause.

Also, this could happen because there's no available connection you can lease which could happen when you don't have timeout config for the HttpClient. In this case, releaseConnection() wouldn't help.

Solution 10 - Java

In my case the bufferedReader that was consuming the entity content stream was not being closed. Closing it resolved the error.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1447011View Question on Stackoverflow
Solution 1 - JavaKrishna GollapudiView Answer on Stackoverflow
Solution 2 - Javauser1447011View Answer on Stackoverflow
Solution 3 - JavaSuyog TilakView Answer on Stackoverflow
Solution 4 - JavaJohan AnderssonView Answer on Stackoverflow
Solution 5 - JavaBrad ParksView Answer on Stackoverflow
Solution 6 - JavaHariJustForFunView Answer on Stackoverflow
Solution 7 - JavaTinkerbellView Answer on Stackoverflow
Solution 8 - JavaAarathiView Answer on Stackoverflow
Solution 9 - JavaSanghyun LeeView Answer on Stackoverflow
Solution 10 - JavaTroy NechanickyView Answer on Stackoverflow