aio-libs/aiohttp · error · ClientConnectionResetError

Connection lost

Error message

Connection lost

What it means

Raised by BaseProtocol._drain_helper (base_protocol.py:133) when self.transport is None, i.e. the connection was already lost (connection_lost ran and nulled the transport) while a drain was pending. aiohttp surfaces this as ClientConnectionResetError('Connection lost'). It is the standard signal that writes are going to a dead connection.

Source

Thrown at aiohttp/base_protocol.py:133

            return
        waiter = self._drain_waiter
        if waiter is None:
            return
        self._drain_waiter = None
        if waiter.done():
            return
        if exc is None:
            waiter.set_result(None)
        else:
            set_exception(
                waiter,
                ConnectionError("Connection lost"),
                exc,
            )

    async def _drain_helper(self) -> None:
        if self.transport is None:
            raise ClientConnectionResetError("Connection lost")
        if not self._paused:
            return
        waiter = self._drain_waiter
        if waiter is None:
            waiter = self._loop.create_future()
            self._drain_waiter = waiter
        await waiter

View on GitHub (pinned to c0ef574e29)

Solutions

  1. Catch ClientConnectionResetError (or its parent ConnectionResetError/ClientConnectionError) around write/drain paths and abort the request cleanly.
  2. Detect disconnection early via the receive side and stop the producer.
  3. Use ClientTimeout and heartbeats so dead connections surface sooner.

Example fix

# before
await resp.write(data)  # raises ClientConnectionResetError if socket gone

# after
try:
    await resp.write(data)
except aiohttp.ClientConnectionResetError:
    # client already disconnected; stop streaming
    return
Defensive patterns

Strategy: try-catch

Try / catch

try:
    await resp.write(data)
except aiohttp.ClientConnectionResetError:
    return  # client already disconnected

Prevention

When it happens

Trigger: A coroutine awaits flow-control drain (implicitly during response body write / websocket send) on a connection whose transport has already been closed by connection_lost.

Common situations: Client writes after the server closed, response streaming into a dropped socket, websocket sends after a network reset, or cancelled tasks draining a closing protocol.

Related errors


AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04). Data as JSON: /data/errors/5003235d250ece0e.json. Report an issue: GitHub.