android network_error ai_generated true

java.net.SocketTimeoutException: timeout. ConnectionPool idle timeout expired. No connection available.

ID: android/okhttp-connection-pool-timeout

Also available as: JSON · Markdown · 中文
80%Fix Rate
86%Confidence
1Evidence
2024-06-20First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
OkHttp 4.11.0 active
OkHttp 4.12.0 active
Android 13 (API 33) active

Root Cause

OkHttp's connection pool has no idle connections available for reuse after the idle timeout (default 5 minutes), and a new connection cannot be established within the configured connect timeout due to network issues or server unavailability.

generic

中文

OkHttp 的连接池在空闲超时(默认 5 分钟)后没有可重用的空闲连接,并且由于网络问题或服务器不可用,无法在配置的连接超时内建立新连接。

Official Documentation

https://square.github.io/okhttp/4.x/okhttp/okhttp3/-connection-pool/

Workarounds

  1. 85% success Increase the idle timeout and pool size in OkHttpClient: `val client = OkHttpClient.Builder().connectionPool(ConnectionPool(10, 10, TimeUnit.MINUTES)).connectTimeout(15, TimeUnit.SECONDS).build()`
    Increase the idle timeout and pool size in OkHttpClient: `val client = OkHttpClient.Builder().connectionPool(ConnectionPool(10, 10, TimeUnit.MINUTES)).connectTimeout(15, TimeUnit.SECONDS).build()`
  2. 80% success Implement retry logic with exponential backoff in your network call: `retryWhen { cause, attempt -> if (cause is SocketTimeoutException && attempt < 3) { delay((1000L * Math.pow(2.0, attempt.toDouble())).toLong()) true } else false }` (Kotlin coroutines example).
    Implement retry logic with exponential backoff in your network call: `retryWhen { cause, attempt -> if (cause is SocketTimeoutException && attempt < 3) { delay((1000L * Math.pow(2.0, attempt.toDouble())).toLong()) true } else false }` (Kotlin coroutines example).

中文步骤

  1. Increase the idle timeout and pool size in OkHttpClient: `val client = OkHttpClient.Builder().connectionPool(ConnectionPool(10, 10, TimeUnit.MINUTES)).connectTimeout(15, TimeUnit.SECONDS).build()`
  2. Implement retry logic with exponential backoff in your network call: `retryWhen { cause, attempt -> if (cause is SocketTimeoutException && attempt < 3) { delay((1000L * Math.pow(2.0, attempt.toDouble())).toLong()) true } else false }` (Kotlin coroutines example).

Dead Ends

Common approaches that don't work:

  1. 90% fail

    The error is about connection pool idle timeout, not connect timeout. Increasing connect timeout does not prevent pool exhaustion; it only delays the failure.

  2. 75% fail

    Disabling pooling forces a new connection for every request, which can cause performance degradation and increase the likelihood of timeout errors under load.