redis/redis-py · error · TimeoutError
Timeout reading from
Error message
Timeout reading from {host_error} What it means
Raised in read_response (connection.py:1416-1419) when socket.timeout fires while reading a reply. This is the read-side counterpart of the write timeout: the server did not produce a complete response within socket_timeout (or the per-call timeout). The connection is disconnected (unless disconnect_on_error=False) and redis.exceptions.TimeoutError is raised, including host:port.
Solutions
- Use the per-call timeout for blocking commands: brpop('q', timeout=30) and read via a client that passes timeout.
- Raise socket_timeout to exceed your slowest expected command.
- Avoid expensive commands on hot paths; prefer SCAN over KEYS.
- Set retry_on_timeout=True if timeouts are expected to be transient.
- For blocking commands, ensure the timeout argument and socket_timeout are consistent.
Example fix
# before
r = redis.Redis(host=h, port=p, socket_timeout=1)
r.brpop('queue', timeout=30) # read times out at 1s
# after
r = redis.Redis(host=h, port=p, socket_timeout=35)
r.brpop('queue', timeout=30) Defensive patterns
Strategy: retry
Validate before calling
# Align socket_timeout with your longest command/block
slowest = 35 # e.g. BLPOP timeout=30 plus margin
r = redis.Redis(
host=h, port=p,
socket_timeout=slowest,
retry_on_timeout=True,
retry=Retry(ExponentialBackoff(), 2),
) Type guard
null
Try / catch
from redis.exceptions import TimeoutError
for _ in range(2):
try:
return r.brpop('queue', timeout=30)
except TimeoutError as e:
if 'reading from' in str(e):
continue
raise Prevention
- For blocking commands set socket_timeout > the block timeout.
- Avoid O(N) commands (KEYS, big SORT) on latency-sensitive paths.
- Use retry_on_timeout=True for transient read stalls.
- Pass per-call timeouts for one-off slow reads.
When it happens
Trigger: A command is sent and read_response is called with a socket_timeout that elapses before the full reply arrives — slow command (KEYS *, large ZRANGE, blocking BLPOP longer than timeout), server stalled, or an explicit per-call timeout passed to read_response that is shorter than the command duration.
Common situations: Blocking commands (BLPOP/BRPOP) with a socket_timeout shorter than the block duration; heavy O(N) commands (SORT, KEYS, SUNION); Lua scripts that run long; server under replication/AOF fsync stall; socket_timeout mis-sized for the workload.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Timeout reading from
- Timeout reading from socket
- Timeout reading from socket
- Error while reading from
- Error while reading from
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/44b2c0ff2a6232e6.
Report an issue: GitHub.
Appendix: source
Thrown at redis/connection.py:1419
"""Read the response from a previously sent command"""
host_error = self._host_error()
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 responseView on GitHub (pinned to 6a6b581b48)