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
- Wrap await ws.prepare(request) in try/except ConnectionResetError and treat it as a closed connection (return early, log at debug).
- Don't treat this as a 5xx — the client is gone, so there is nobody to send an error response to.
- 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
- Wrap ws.prepare() in try/except ConnectionResetError on flaky networks.
- Don't log ConnectionResetError at error level — it's expected client churn.
- Consider connection-count limits to bound the impact of churn.
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
- Already started
- Call .prepare() first
- Cannot write to closing transport
- Connection closed.
- Connection lost
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)