aio-libs/aiohttp · error · ConnectionTimeoutError

Connection timeout to host {req.url}

Error message

Connection timeout to host {req.url}

What it means

Raised in _connect_and_send_request (client.py:239-240) when the connector's connection attempt times out. connector.connect() raises asyncio.TimeoutError once the configured connect timeout elapses, and aiohttp wraps it as ConnectionTimeoutError('Connection timeout to host {url}'), a subclass of ServerTimeoutError/ClientError.

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 d9aaf697c2)

Solutions

  1. Increase the connect timeout: ClientTimeout(connect=30) or pass timeout= to the request.
  2. Verify reachability of the host/port (DNS resolves, firewall allows, service is up).
  3. Retry the request with backoff for transient network issues.
  4. Check proxy configuration (HTTPS_PROXY/HTTP_PROXY) and the connection pool limit.

Example fix

// before
async with aiohttp.ClientSession() as s:
    await s.get('https://slow.example.com')  # default connect timeout
// after (explicit connect timeout + retry)
import asyncio
from aiohttp import ClientTimeout
async with aiohttp.ClientSession(timeout=ClientTimeout(connect=30)) as s:
    for attempt in range(3):
        try:
            return await s.get('https://slow.example.com')
        except asyncio.TimeoutError:
            await asyncio.sleep(2 ** attempt)
Defensive patterns

Strategy: retry

Validate before calling

import socket
# pre-flight reachability check (optional)
try:
    socket.create_connection((host, port), timeout=5).close()
except OSError:
    skip_request()

Try / catch

import asyncio
from aiohttp import ClientTimeout, ConnectionTimeoutError
for attempt in range(3):
    try:
        return await session.get(url, timeout=ClientTimeout(connect=30))
    except (ConnectionTimeoutError, asyncio.TimeoutError):
        if attempt == 2:
            raise
        await asyncio.sleep(2 ** attempt)

Prevention

When it happens

Trigger: The TCP (and TLS) handshake to the target host does not complete within ClientTimeout.connect (default 5 minutes, often overridden lower). The await connector.connect(...) inside _connect_and_send_request crosses the deadline.

Common situations: An unreachable/slow host, a firewall dropping SYN packets, a saturated connection pool, a misconfigured proxy, or connect timeout set too low for a high-latency link.

Understand the failure class

Related errors


AI-assisted analysis of aio-libs/aiohttp@d9aaf697c2 (2026-08-06). Data as JSON: /api/errors/fccc8e0edcaf67c7. Report an issue: GitHub.