redis/redis-py · error · TimeoutError
Timeout reading from socket
Error message
Timeout reading from socket
What it means
Raised by the sync hiredis parser's read_from_socket when a non-blocking recv (BlockingIOError/SSLWantReadError with matching errno) occurs with timeout == 0 and raise_on_timeout is True. It surfaces as redis.exceptions.TimeoutError because a zero-timeout poll found no data and the caller asked to be told.
Source
Thrown at redis/_parsers/hiredis.py:213
reader.feed(self._buffer, 0, bufflen)
# data was read from the socket and added to the buffer.
# return True to indicate that data was read.
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:
if custom_timeout:
sock.settimeout(self._socket_timeout)
def read_response(
self,
disable_decoding=False,
push_request=False,
timeout: Union[float, object] = SENTINEL,
):
# Bind the reader locally so a concurrent disconnect that clears
# self._reader can't turn a later .gets() into an AttributeError;
# re-checking the attribute each time would still race.
reader = self._reader
if reader is None:
raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR)
View on GitHub (pinned to 43bf5ac31a)
Solutions
- Use a small positive socket_timeout (e.g. 0.5s) instead of 0.
- For pubsub polls, pass an explicit positive timeout to get_message() rather than relying on socket_timeout=0.
- Catch redis.TimeoutError and retry with backoff; treat it as transient.
- Scale/shard Redis if the server is genuinely too busy to respond in time.
Example fix
# before
r = redis.Redis(host='redis', socket_timeout=0)
r.get('k')
# after
r = redis.Redis(host='redis', socket_timeout=0.5)
r.get('k') Defensive patterns
Strategy: retry
Validate before calling
# Reject a zero socket_timeout before constructing the client.
if socket_timeout == 0:
raise ValueError('socket_timeout=0 forces zero-timeout reads; use a small positive value')
r = redis.Redis(host=host, socket_timeout=socket_timeout) Type guard
def is_zero_timeout(exc: Exception) -> bool:
from redis.exceptions import TimeoutError
return isinstance(exc, TimeoutError) and 'Timeout reading from socket' in str(exc) Try / catch
from redis.exceptions import TimeoutError
import time
for backoff in (0.1, 0.2, 0.4):
try:
return r.get('k')
except TimeoutError:
time.sleep(backoff)
raise TimeoutError('redis read timed out after retries') Prevention
- Never set socket_timeout=0 in production.
- Give pubsub polls a real timeout.
- Distinguish transient TimeoutError from hard failures in your retry policy.
When it happens
Trigger: Calling can_read()/health-check/pubsub poll with socket_timeout=0, or a read against a busy server / not-yet-ready TLS handshake where plaintext isn't available within a zero-length window.
Common situations: Setting `socket_timeout=0` thinking it means 'no timeout'; pubsub.get_message(timeout=0) loops on slow links; TLS connections that yield SSLWantReadError before the handshake completes; very busy single-threaded Redis blocking the read.
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.
- Connection closed by server.
- Connection closed by server.
- Connection closed by server.
AI-assisted analysis of redis/redis-py@43bf5ac31a (2026-08-06).
Data as JSON: /api/errors/9ad1ed7c8be59a33.
Report an issue: GitHub.