{"id":"f022574f1b8d1499","repo":"redis/redis-py","slug":"error-while-reading-from-host-error-e-args-f02257","errorCode":null,"errorMessage":"Error while reading from {host_error} : {e.args}","messagePattern":"Error while reading from (.+?) : (.+?)","errorType":"exception","errorClass":"ConnectionError","httpStatus":null,"severity":"error","filePath":"redis/asyncio/connection.py","lineNumber":1314,"sourceCode":"                            push_request=push_request,\n                        )\n            else:\n                response = await self._read_response_from_parser(\n                    disable_decoding=disable_decoding,\n                    push_request=push_request,\n                )\n        except asyncio.TimeoutError:\n            if timeout is not None:\n                # user requested timeout, return None. Operation can be retried\n                return None\n            # it was a self.socket_timeout error.\n            if disconnect_on_error:\n                await self.disconnect(nowait=True)\n            raise TimeoutError(f\"Timeout reading from {host_error}\")\n        except OSError as e:\n            if disconnect_on_error:\n                await self.disconnect(nowait=True)\n            raise ConnectionError(f\"Error while reading from {host_error} : {e.args}\")\n        except BaseException:\n            # Also by default close in case of BaseException.  A lot of code\n            # relies on this behaviour when doing Command/Response pairs.\n            # See #1128.\n            if disconnect_on_error:\n                await self.disconnect(nowait=True)\n            raise\n\n        if self.health_check_interval:\n            next_time = asyncio.get_running_loop().time() + self.health_check_interval\n            self.next_health_check = next_time\n\n        if isinstance(response, ResponseError):\n            raise response from None\n        return response\n\n    async def _read_response_from_parser(\n        self, disable_decoding: bool = False, push_request: bool | None = False","sourceCodeStart":1296,"sourceCodeEnd":1332,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/asyncio/connection.py#L1296-L1332","documentation":"Raised as a ConnectionError from read_response() when the parser raises an OSError while reading. The connection is forcibly disconnected (nowait=True) because a partial read desynchronizes the protocol. The host:port (or UDS path) and the OSError args are included. This is the canonical 'broken socket while reading a response' failure.","triggerScenarios":"Any command's read_response() where the socket raises OSError mid-read: server closed the connection (ECONNRESET), TCP RST from a firewall, local socket already closed (EBADF), or the parser hit an IO error decoding the stream.","commonSituations":"Server restarted/crashed during a long-running command; idle connection reaped by a firewall (RST on next read); OOM-kill of the server; client/server on different subnets with packet loss; reusing a disconnected connection.","solutions":["Configure retry (retry_on_error=[ConnectionError]) with backoff so transient resets are retried automatically.","Enable health_check_interval to evict dead connections before they are read from.","Enable socket_keepalive so silent drops are detected by the kernel rather than failing the next read.","Inspect e.args to distinguish ECONNRESET (peer closed) from EBADF (local misuse) or ETIMEDOUT."],"exampleFix":"// before\nr = redis.asyncio.Redis(host=h, port=p)\n\n// after\nfrom redis.backoff import ExponentialWithJitterBackoff\nfrom redis.retry import Retry\nfrom redis.exceptions import ConnectionError\nretry = Retry(ExponentialWithJitterBackoff(), 3)\nr = redis.asyncio.Redis(host=h, port=p, retry=retry, retry_on_error=[ConnectionError], health_check_interval=30)","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"from redis.exceptions import ConnectionError\nfor attempt in range(3):\n    try:\n        val = await r.get(\"k\")\n        break\n    except ConnectionError as e:\n        if \"while reading from\" in str(e):\n            await asyncio.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Configure retry_on_error=[ConnectionError].","Enable health_check_interval and socket_keepalive.","Let the pool reconnect instead of reusing a dead connection."],"tags":["network","read","connection-reset","broken-pipe","async"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}