redis/redis-py · error · ConnectionError

Error while reading from

Error message

Error while reading from {host_error} : {e.args}

What it means

Raised in read_response (connection.py:1420-1423) as the generic OSError branch (after socket.timeout) while reading a reply. The underlying OS error args are included with host:port. Like the timeout case the connection is disconnected unless disconnect_on_error=False. It typically reflects a reset/closed peer or a corrupt read rather than a timeout.

Solutions

  1. Catch ConnectionError and retry via the pool (idempotent commands only).
  2. Use Sentinel/cluster for automatic failover to a healthy node.
  3. Enable health_check_interval + socket_keepalive to detect drops earlier.
  4. Check server INFO / dmesg for OOM or maxclients events.
  5. For non-idempotent ops, use MULTI/EXEC or a dedupe key before retrying.

Example fix

# before
val = r.get('k')  # raises mid-response
# after
from redis.exceptions import ConnectionError
for _ in range(3):
    try:
        val = r.get('k'); break
    except ConnectionError:
        pass
Defensive patterns

Strategy: try-catch

Validate before calling

# Resilient defaults + automatic failover
r = redis.Redis(
    host=h, port=p,
    health_check_interval=30,
    socket_keepalive=True,
    socket_timeout=5,
    retry_on_error=[redis.ConnectionError],
)
# Prefer Sentinel/cluster for HA so failed nodes are skipped
sentinel = redis.Sentinel([(h, 26379)], socket_timeout=0.5)
master = sentinel.master_for('mymaster')

Type guard

null

Try / catch

from redis.exceptions import ConnectionError
for _ in range(3):
    try:
        return r.get('k')  # idempotent read
    except ConnectionError:
        continue
raise ConnectionError('Redis unavailable after retries')

Prevention

When it happens

Trigger: read_response encounters socket read error other than timeout — peer ECONNRESET mid-response, EPIPE, EBADF, truncated frame after a server-side disconnect, or a corrupt RESP stream that surfaces as an OSError in the low-level read.

Common situations: Server restarted/failed over; OOM kill of Redis dropping connections; network partition mid-response; maxclients eviction; a proxy closing the upstream after its own timeout.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/20e36bbddbdf5150. Report an issue: GitHub.

Appendix: source

Thrown at redis/connection.py:1423

        try:
            if self.protocol in ["3", 3]:
                response = self._parser.read_response(
                    disable_decoding=disable_decoding,
                    push_request=push_request,
                    timeout=timeout,
                )
            else:
                response = self._parser.read_response(
                    disable_decoding=disable_decoding, timeout=timeout
                )
        except socket.timeout:
            if disconnect_on_error:
                self.disconnect()
            raise TimeoutError(f"Timeout reading from {host_error}")
        except OSError as e:
            if disconnect_on_error:
                self.disconnect()
            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:
                self.disconnect()
            raise

        if self.health_check_interval:
            self.next_health_check = time.monotonic() + self.health_check_interval

        if isinstance(response, ResponseError):
            try:
                raise response
            finally:
                del response  # avoid creating ref cycles
        return response

View on GitHub (pinned to 6a6b581b48)