{"record":{"id":"6c1bf51d15328a0b","repo":"redis/redis-py","slug":"timeout-reading-from-socket-6c1bf5","errorCode":null,"errorMessage":"Timeout reading from socket","messagePattern":"Timeout reading from socket","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"redis/_parsers/socket.py","lineNumber":77,"sourceCode":"        buf.seek(0, SEEK_END)\n        if custom_timeout:\n            sock.settimeout(timeout)\n        try:\n            while True:\n                data = sock.recv(socket_read_size)\n                # an empty string indicates the server shutdown the socket\n                if isinstance(data, bytes) and len(data) == 0:\n                    raise ConnectionError(SERVER_CLOSED_CONNECTION_ERROR)\n                buf.write(data)\n                data_length = len(data)\n                marker += data_length\n\n                if length is not None and length > marker:\n                    continue\n                return True\n        except socket.timeout:\n            if raise_on_timeout:\n                raise TimeoutError(\"Timeout reading from socket\")\n            return False\n        except NONBLOCKING_EXCEPTIONS as ex:\n            # if we're in nonblocking mode and the recv raises a\n            # blocking error, simply return False indicating that\n            # there's no data to be read. otherwise raise the\n            # original exception.\n            allowed = NONBLOCKING_EXCEPTION_ERROR_NUMBERS.get(ex.__class__, -1)\n            if ex.errno == allowed:\n                if not raise_on_timeout:\n                    return False\n                if timeout == 0:\n                    raise TimeoutError(\"Timeout reading from socket\")\n            raise ConnectionError(f\"Error while reading from socket: {ex.args}\")\n        finally:\n            buf.seek(current_pos)\n            if custom_timeout:\n                sock.settimeout(self.socket_timeout)\n","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/_parsers/socket.py#L59-L95","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nr = redis.Redis(socket_timeout=0.5)  # pure-Python path\nr.blpop('q', timeout=10)  # -> TimeoutError: Timeout reading from socket\n\n# after - timeout covers the block window\nr = redis.Redis(socket_timeout=12)\nr.blpop('q', timeout=10)","handlingStrategy":"retry","validationCode":"def timeout_ok(r, block_seconds):\n    st = r.connection_pool.connection_kwargs.get('socket_timeout')\n    return st is None or st > block_seconds","typeGuard":"from redis.exceptions import TimeoutError as RedisTimeoutError\n\ndef is_socket_read_timeout(e: BaseException) -> bool:\n    return isinstance(e, RedisTimeoutError) and str(e) == 'Timeout reading from socket'","tryCatchPattern":"from redis.exceptions import TimeoutError\nimport time\nfor attempt in range(3):\n    try:\n        return r.get('k')\n    except TimeoutError:\n        if attempt == 2:\n            raise\n        time.sleep(0.2 * (2 ** attempt))","preventionTips":["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."],"tags":["timeout","network","sync","socket","blocking-commands"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}