aio-libs/aiohttp · error · ConnectionTimeoutError
Connection timeout to host
Error message
Connection timeout to host {req.url} What it means
Raised as ConnectionTimeoutError('Connection timeout to host {url}') in _connect_and_send_request when the connector's connect() call raises asyncio.TimeoutError. This means the TCP connection (and any TLS handshake governed by the connect phase) did not complete within the configured timeout window. The original asyncio.TimeoutError is chained as the cause.
Solutions
- Increase ClientTimeout total and/or sock_connect to match the real network conditions.
- Verify the URL/host is reachable and DNS resolves (test with a raw socket or curl).
- Retry with exponential backoff for transient failures.
- If using a proxy or connector pool, check the proxy health and pool limit/limit_per_host settings.
- For slow TLS handshakes, ensure ssl timeouts and SNI are configured correctly.
Example fix
// before
async with aiohttp.ClientSession(timeout=ClientTimeout(sock_connect=0.5)) as s:
await s.get(url) // ConnectionTimeoutError
// after
async with aiohttp.ClientSession(timeout=ClientTimeout(total=30, sock_connect=10)) as s:
await s.get(url) Defensive patterns
Strategy: retry
Validate before calling
// Right-size the timeout for the target's real latency.
timeout = aiohttp.ClientTimeout(total=30, sock_connect=10, sock_read=30)
async with aiohttp.ClientSession(timeout=timeout) as session:
...
Type guard
null
Try / catch
for attempt in range(MAX_RETRIES):
try:
async with session.get(url, timeout=timeout) as resp:
return await resp.read()
except aiohttp.ConnectionTimeoutError:
backoff = 2 ** attempt
await asyncio.sleep(backoff)
raise
Prevention
- Set sock_connect/total to match worst-case network conditions, not best-case.
- Verify reachability and DNS independently before retrying.
- Retry transient timeouts with exponential backoff.
- Check proxy health and connector pool limits (limit, limit_per_host).
When it happens
Trigger: await connector.connect(req, traces=..., timeout=req._timeout) does not finish before the relevant timeout (total or sock_connect) elapses, raising asyncio.TimeoutError, which _connect_and_send_request converts to ConnectionTimeoutError. Typical with a slow/unreachable host, a blocking DNS lookup, or an over-tight sock_connect value.
Common situations: The target host is unreachable or firewalled (SYN with no SYN-ACK); DNS resolution is slow; an over-restrictive ClientTimeout(sock_connect=...) or total=...; a proxy that stalls; connection pool exhaustion making connect wait; transient network blips or cloud cold-start latency.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- total timeout must be a positive number or None to disable…
- aiohttp only supports http(s) proxies
- compress can not be set if Content-Encoding header is set
- compress must be one of True, False, 'deflate', or 'gzip'
- Connection closed
AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11).
Data as JSON: /api/errors/fccc8e0edcaf67c7.
Report an issue: GitHub.
Appendix: source
Thrown at aiohttp/client.py:240
)
_RetType_co = TypeVar(
"_RetType_co",
bound="ClientResponse | ClientWebSocketResponse[bool]",
covariant=True,
)
_CharsetResolver = Callable[[ClientResponse, bytes], str]
# Module-level (not a closure) so it has a stable identity for the
# ``_cached_build_client_middlewares`` cache key.
async def _connect_and_send_request(req: ClientRequest) -> ClientResponse:
connector = req._session._connector
assert connector is not None
try:
conn = await connector.connect(req, traces=req._traces, timeout=req._timeout)
except asyncio.TimeoutError as exc:
raise ConnectionTimeoutError(f"Connection timeout to host {req.url}") from exc
assert conn.protocol is not None
conn.protocol.set_response_params(**req._response_params)
try:
resp = await req._send(conn)
try:
await resp.start(conn)
except BaseException:
resp.close()
raise
except BaseException:
conn.close()
raise
return resp
@final
class ClientSession:View on GitHub (pinned to d041d4d0fd)