aio-libs/aiohttp · warning · ConnectionResetError

Connection lost

Error message

Connection lost

What it means

In _pre_start(), after the handshake succeeds, aiohttp fetches request._protocol.transport to build the WebSocketWriter. If the transport is already None (the underlying connection was closed/reset between the request arriving and prepare() running), it raises ConnectionResetError('Connection lost'). This is a network-level condition, not a programmer error — the client disconnected mid-handshake.

Solutions

  1. Wrap await ws.prepare(request) in try/except ConnectionResetError and treat it as a closed connection (return early, log at debug).
  2. Don't treat this as a 5xx — the client is gone, so there is nobody to send an error response to.
  3. Tune keepalive/timeout settings if this floods logs; consider connection-count limits.

Example fix

// before
ws = web.WebSocketResponse()
await ws.prepare(request)
async for msg in ws: ...
// after
ws = web.WebSocketResponse()
try:
    await ws.prepare(request)
except ConnectionResetError:
    return ws  # client gone; nothing to send
async for msg in ws: ...
Defensive patterns

Strategy: try-catch

Validate before calling

def connection_still_alive(request) -> bool:
    return getattr(request._protocol, 'transport', None) is not None

Type guard

def transport_present(request) -> bool:
    return request._protocol.transport is not None

Try / catch

ws = web.WebSocketResponse()
try:
    await ws.prepare(request)
except ConnectionResetError:
    log.debug('client disconnected during WS handshake')
    return ws  # nothing to send; client is gone

Prevention

When it happens

Trigger: Client closes the TCP connection immediately after sending the upgrade request (double-click, abrupt close); a network device reset the connection; the connection timed out at the OS level just as the handler started; high-latency/flaky mobile clients.

Common situations: Flaky mobile networks; load balancer health checks that open then immediately close; clients with very short timeouts; misbehaving browser tabs closed right after connecting; abuse from scanners opening sockets and dropping them.

Related errors


AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11). Data as JSON: /api/errors/58c61ec4847764c2. Report an issue: GitHub.

Appendix: source

Thrown at aiohttp/web_ws.py:365

        return (
            response_headers,
            protocol,
            compress,
            notakeover,
        )

    def _pre_start(self, request: BaseRequest) -> tuple[str | None, WebSocketWriter]:
        self._loop = request._loop

        headers, protocol, compress, notakeover = self._handshake(request)

        self.set_status(101)
        self.headers.update(headers)
        self.force_close()
        self._compress = compress
        transport = request._protocol.transport
        if transport is None:
            raise ConnectionResetError("Connection lost")
        writer = WebSocketWriter(
            request._protocol,
            transport,
            compress=compress,
            notakeover=notakeover,
            limit=self._writer_limit,
        )

        return protocol, writer

    def _post_start(
        self, request: BaseRequest, protocol: str | None, writer: WebSocketWriter
    ) -> None:
        self._ws_protocol = protocol
        self._writer = writer

        self._reset_heartbeat()

View on GitHub (pinned to d041d4d0fd)