redis/redis-py · error · ConnectionError
Error while reading from {host_error} : {e.args}
Error message
Error while reading from {host_error} : {e.args} What it means
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.
Source
Thrown at redis/asyncio/connection.py:1314
push_request=push_request,
)
else:
response = await self._read_response_from_parser(
disable_decoding=disable_decoding,
push_request=push_request,
)
except asyncio.TimeoutError:
if timeout is not None:
# user requested timeout, return None. Operation can be retried
return None
# it was a self.socket_timeout error.
if disconnect_on_error:
await self.disconnect(nowait=True)
raise TimeoutError(f"Timeout reading from {host_error}")
except OSError as e:
if disconnect_on_error:
await self.disconnect(nowait=True)
raise ConnectionError(f"Error while reading from {host_error} : {e.args}")
except BaseException:
# Also by default close in case of BaseException. A lot of code
# relies on this behaviour when doing Command/Response pairs.
# See #1128.
if disconnect_on_error:
await self.disconnect(nowait=True)
raise
if self.health_check_interval:
next_time = asyncio.get_running_loop().time() + self.health_check_interval
self.next_health_check = next_time
if isinstance(response, ResponseError):
raise response from None
return response
async def _read_response_from_parser(
self, disable_decoding: bool = False, push_request: bool | None = FalseView on GitHub (pinned to da03cdc7e8)
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.
Example fix
// before r = redis.asyncio.Redis(host=h, port=p) // after from redis.backoff import ExponentialWithJitterBackoff from redis.retry import Retry from redis.exceptions import ConnectionError retry = Retry(ExponentialWithJitterBackoff(), 3) r = redis.asyncio.Redis(host=h, port=p, retry=retry, retry_on_error=[ConnectionError], health_check_interval=30)
Defensive patterns
Strategy: retry
Try / catch
from redis.exceptions import ConnectionError
for attempt in range(3):
try:
val = await r.get("k")
break
except ConnectionError as e:
if "while reading from" in str(e):
await asyncio.sleep(2 ** attempt)
continue
raise Prevention
- Configure retry_on_error=[ConnectionError].
- Enable health_check_interval and socket_keepalive.
- Let the pool reconnect instead of reusing a dead connection.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Error {err_no} while writing to socket. {errmsg}.
- Error while reading from {host_error}: {e.args}
- Timeout reading from {host_error}
- Error while reading from {host_error}: {e.args}
- Error while reading from {host_error} : {e.args}
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/f022574f1b8d1499.json.
Report an issue: GitHub.