android network_error ai_generated true

java.net.SocketException: recvfrom失败: ETIMEDOUT(连接超时)在okhttp3.internal.http2.Http2Connection$ReaderRunnable.onSettings

java.net.SocketException: recvfrom failed: ETIMEDOUT (Connection timed out) at okhttp3.internal.http2.Http2Connection$ReaderRunnable.onSettings

ID: android/backpressure-queue-overflow-in-okhttp

其他格式: JSON · Markdown 中文 · English
82%修复率
85%置信度
1证据数
2023-06-15首次发现

版本兼容性

版本状态引入弃用备注
OkHttp 4.12.0 active
Android 14 (API 34) active
Android 13 (API 33) active
OkHttp 3.12.13 active

根因分析

OkHttp的HTTP/2连接背压机制在服务器SETTINGS帧未在默认2秒窗口内确认时触发超时,通常是由于网络缓慢或服务器端连接饱和。

English

OkHttp's HTTP/2 connection backpressure mechanism triggers a timeout when the server's SETTINGS frame is not acknowledged within the default 2-second window, often due to slow network or server-side connection saturation.

generic

官方文档

https://square.github.io/okhttp/4.x/okhttp/okhttp3/-ok-http-client/

解决方案

  1. Configure OkHttp to use a custom dispatcher with maxRequestsPerHost=1 and retryOnConnectionFailure(true) to reduce backpressure pressure. Example: new OkHttpClient.Builder().dispatcher(new Dispatcher() {{ setMaxRequestsPerHost(1); }}).retryOnConnectionFailure(true).build()
  2. Set a custom socket factory that adjusts the SO_TIMEOUT to 5000ms on the underlying socket before the HTTP/2 connection is established. Example: OkHttpClient.Builder().socketFactory(new SocketFactory() { ... });
  3. Upgrade OkHttp to version 4.12.0 or later which includes a fix for the backpressure timeout handling in the HTTP/2 reader loop.

无效尝试

常见但无效的做法:

  1. Increase OkHttp connectTimeout to 30 seconds 90% 失败

    connectTimeout controls the initial TCP handshake, not the SETTINGS acknowledgment timeout. The backpressure timeout is hardcoded in OkHttp's HTTP/2 implementation at 2 seconds.

  2. Disable HTTP/2 entirely by setting protocol to Protocol.HTTP_1_1 70% 失败

    While this avoids the error, it disables multiplexing and header compression, degrading performance for all requests. The underlying server or network issue remains unaddressed.

  3. Increase readTimeout to 60 seconds 95% 失败

    readTimeout applies to individual stream reads, not the connection-level SETTINGS exchange. The backpressure timeout is independent and remains at 2 seconds.