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 a non-blocking recv (BlockingIOError/SSLWantReadError, matching errno) occurs with timeout == 0. It surfaces as redis.exceptions.TimeoutError — a zero-timeout poll found no data and the caller asked to be notified.
Source
Thrown at redis/_parsers/socket.py:89
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)
def can_read(self, timeout: float = 0) -> bool:
return bool(self.unread_bytes()) or self._read_from_socket(
timeout=timeout, raise_on_timeout=False
)
def read(self, length: int, timeout: Union[float, object] = SENTINEL) -> bytes:
length = length + 2 # make sure to read the \r\n terminator
# BufferIO will return less than requested if buffer is short
data = self._buffer.read(length)
missing = length - len(data)
if missing:
# fill up the buffer and read the remainderView on GitHub (pinned to 43bf5ac31a)
Solutions
- Use a small positive socket_timeout (e.g. 0.5s).
- Pass an explicit positive timeout to pubsub.get_message().
- Catch redis.TimeoutError and retry with backoff.
- Scale Redis if it's genuinely too slow to respond.
Example fix
# before
r = redis.Redis(host='redis', socket_timeout=0)
r.get('k')
# after
r = redis.Redis(host='redis', socket_timeout=0.5) Defensive patterns
Strategy: retry
Validate before calling
if socket_timeout == 0:
raise ValueError('use a positive socket_timeout')
r = redis.Redis(host=host, socket_timeout=socket_timeout) Type guard
def is_socket_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.
- Give pubsub polls a real timeout.
- Distinguish TimeoutError from hard failures in retry policy.
When it happens
Trigger: can_read()/pubsub poll/health check with socket_timeout=0 against a busy server or a TLS connection whose plaintext isn't ready within the zero window.
Common situations: Setting socket_timeout=0; tight pubsub.get_message(timeout=0) loops on slow links; TLS yielding SSLWantReadError before handshake; overloaded single-threaded Redis.
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 writing to socket
- Timeout reading from {host_error}
- Timeout writing to socket
AI-assisted analysis of redis/redis-py@43bf5ac31a (2026-08-06).
Data as JSON: /api/errors/6c1bf51d15328a0b.
Report an issue: GitHub.