redis/redis-py · error · TimeoutError
Timeout reading from socket
Error message
Timeout reading from socket
What it means
Raised by SocketBuffer._read_from_socket when sock.recv() raises socket.timeout with raise_on_timeout=True (the default). Pure-Python parser counterpart of error 21. redis.exceptions.TimeoutError (error_type=NETWORK), which does NOT subclass Python's builtin TimeoutError.
Solutions
- Raise socket_timeout to exceed the slowest expected command/block time.
- For blocking commands, keep their block argument below socket_timeout, or pass a higher per-call timeout.
- Avoid KEYS/SMEMBERS in production; use SCAN.
- Add retry with backoff for TimeoutError via retry_on_error=[TimeoutError].
- Inspect SLOWLOG GET and optimize long commands.
Example fix
# before
r = redis.Redis(socket_timeout=0.5) # pure-Python path
r.blpop('q', timeout=10) # -> TimeoutError: Timeout reading from socket
# after - timeout covers the block window
r = redis.Redis(socket_timeout=12)
r.blpop('q', timeout=10) Defensive patterns
Strategy: retry
Validate before calling
def timeout_ok(r, block_seconds):
st = r.connection_pool.connection_kwargs.get('socket_timeout')
return st is None or st > block_seconds Type guard
from redis.exceptions import TimeoutError as RedisTimeoutError
def is_socket_read_timeout(e: BaseException) -> bool:
return isinstance(e, RedisTimeoutError) and str(e) == 'Timeout reading from socket' Try / catch
from redis.exceptions import TimeoutError
import time
for attempt in range(3):
try:
return r.get('k')
except TimeoutError:
if attempt == 2:
raise
time.sleep(0.2 * (2 ** attempt)) Prevention
- Don't catch the builtin TimeoutError - redis raises redis.exceptions.TimeoutError, which does not subclass it.
- Set socket_timeout strictly greater than any BLOCK time you pass to BLPOP/BZPOPMIN/XREAD.
- Never run KEYS in production; its wall time is unbounded.
When it happens
Trigger: A pure-Python (non-hiredis) sync connection where a reply takes longer than socket_timeout to arrive: KEYS / SORT / bigkey GET, blocking commands (BLPOP/BZPOPMIN/XREAD BLOCK) whose block time exceeds socket_timeout, slow/congested network, server stalled under RDB/AOF load.
Common situations: Low socket_timeout against a loaded Redis; KEYS in production; BLPOP block time greater than the client socket_timeout; cross-region latency spikes; AOF fsync=always stalls.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Timeout reading from socket
- Connection closed by server.
- Timeout reading from
- Connection closed by server.
- Connection closed by server.
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/6c1bf51d15328a0b.
Report an issue: GitHub.
Appendix: source
Thrown at redis/_parsers/socket.py:77
buf.seek(0, SEEK_END)
if custom_timeout:
sock.settimeout(timeout)
try:
while True:
data = sock.recv(socket_read_size)
# an empty string indicates the server shutdown the socket
if isinstance(data, bytes) and len(data) == 0:
raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR)
buf.write(data)
data_length = len(data)
marker += data_length
if length is not None and length > marker:
continue
return True
except socket.timeout:
if raise_on_timeout:
raise TimeoutError("Timeout reading from socket")
return False
except NONBLOCKING_EXCEPTIONS as ex:
# if we're in nonblocking mode and the recv raises a
# blocking error, simply return False indicating that
# there's no data to be read. otherwise raise the
# original exception.
allowed = NONBLOCKING_EXCEPTION_ERROR_NUMBERS.get(ex.__class__, -1)
if ex.errno == allowed:
if not raise_on_timeout:
return False
if timeout == 0:
raise TimeoutError("Timeout reading from socket")
raise ConnectionError(f"Error while reading from socket: {ex.args}")
finally:
buf.seek(current_pos)
if custom_timeout:
sock.settimeout(self.socket_timeout)
View on GitHub (pinned to 6a6b581b48)