{"record":{"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/6a6b581b48225afa0b76912d1028c6035baee932/redis/asyncio/connection.py#L1296-L1332","documentation":"Raised as ConnectionError from read_response() when the parser/reader raises OSError (not TimeoutError). Same path as the write-side OSError: the connection is disconnected nowait and re-raised with host_error and the OSError args. Note the message has a space before the colon, distinguishing it from the can_read variants.","triggerScenarios":"Reading any response when the peer has reset/closed the socket mid-reply; partial RESP frame then RST; TLS truncation; reader feed_eof with exception. The first read after a dead-pool-reuse surfaces here.","commonSituations":"Server failover; LB idle eviction between request and response; client-output-buffer-limit disconnecting during a big bulk reply; forked process sharing the reader; abrupt server kill -9.","solutions":["Enable retry on ConnectionError with a bounded backoff for idempotent commands.","Reduce response sizes or raise server client-output-buffer-limit to avoid mid-reply disconnects.","Enable socket_keepalive to surface dead peers sooner.","Verify the deployment is not running two clients on the same descriptor (no socket sharing across fork)."],"exampleFix":"// before\nr = redis.asyncio.Redis(host=h)\n// after\nfrom redis.retry import Retry\nfrom redis.backoff import ExponentialBackoff\nr = redis.asyncio.Redis(host=h, retry=Retry(ExponentialBackoff(), 3), retry_on_error=[ConnectionError], socket_keepalive=True)","handlingStrategy":"retry","validationCode":"null","typeGuard":"from redis.exceptions import ConnectionError\n\ndef is_read_error(exc: BaseException) -> bool:\n    msg = str(exc).lower()\n    return isinstance(exc, ConnectionError) and 'reading from' in msg and ':' in msg","tryCatchPattern":"from redis.retry import Retry\nfrom redis.backoff import ExponentialBackoff\nfrom redis.exceptions import ConnectionError\n\nr = redis.asyncio.Redis(\n    host=h,\n    retry=Retry(ExponentialBackoff(), 3),\n    retry_on_error=[ConnectionError],\n    socket_keepalive=True,\n)","preventionTips":["Enable retry_on_error=[ConnectionError] for idempotent reads.","Raise client-output-buffer-limit for large bulk replies.","Never share a connection across forked processes."],"tags":["network","oserror","read","connection-reset","async","retry","host-error"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}