{"record":{"id":"fcf5eff9625f284e","repo":"redis/redis-py","slug":"connection-not-ready-fcf5ef","errorCode":null,"errorMessage":"Connection not ready","messagePattern":"Connection not ready","errorType":"exception","errorClass":"ConnectionError","httpStatus":null,"severity":"error","filePath":"redis/connection.py","lineNumber":3309,"sourceCode":"            # a command. if not, the connection was either returned to the\n            # pool before all data has been read or the socket has been\n            # closed. either way, reconnect and verify everything is good.\n            try:\n                if (\n                    connection.can_read()\n                    and self.cache is None\n                    and not self.maint_notifications_enabled()\n                ):\n                    raise ConnectionError(\"Connection has data\")\n            except (ConnectionError, TimeoutError, OSError):\n                connection.disconnect()\n                connection.connect()\n                if (\n                    connection.can_read()\n                    and self.cache is None\n                    and not self.maint_notifications_enabled()\n                ):\n                    raise ConnectionError(\"Connection not ready\")\n        except BaseException:\n            # release the connection back to the pool so that we don't\n            # leak it\n            self.release(connection)\n            raise\n\n        if is_created:\n            record_connection_create_time(\n                connection_pool=self,\n                duration_seconds=time.monotonic() - start_time_created,\n            )\n\n        return connection\n\n    def get_encoder(self) -> Encoder:\n        \"Return an encoder based on encoding settings\"\n        kwargs = self.connection_kwargs\n        return Encoder(","sourceCodeStart":3291,"sourceCodeEnd":3327,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/connection.py#L3291-L3327","documentation":"Raised as ConnectionError('Connection not ready') by ConnectionPool.get_connection / the blocking pool after a connection that still had unread socket data was disconnected and reconnected and still reports can_read() True (and client-side caching and maintenance notifications are not active, which would legitimately leave push data on the socket). It indicates the reconnected socket is not in a clean command-ready state, so handing it out would corrupt the request/response framing.","triggerScenarios":"A pooled connection was returned with unread bytes (e.g. a previous command's reply not fully consumed, or an unsolicited server push), the pool disconnects/reconnects, and the fresh socket still shows pending data — typically due to a server-side push, a half-read pipeline reply, or a flaky network path.","commonSituations":"Not fully consuming responses (abandoned read_response). Server pushing data right after connect. Aggressive health-check or pubsub traffic on a non-cache, non-maintenance pool. Transient socket corruption.","solutions":["Ensure every command's response is fully read before returning the connection to the pool (avoid partial reads in pipelines/transactions).","Treat this as transient and retry the operation with backoff; the pool releases the bad connection on raise.","If it recurs, enable client-side caching or maintenance notifications only where appropriate, or review for server push traffic the client isn't expecting."],"exampleFix":"# before - response not fully consumed, conn returned dirty\npipe = r.pipeline()\npipe.set('a', 1)\npipe.execute()  # partially read elsewhere -> next get_connection can raise\n# after - always drain the response, and retry on transient ConnectionError\nfor attempt in range(3):\n    try:\n        return r.get('a')\n    except redis.exceptions.ConnectionError:\n        continue","handlingStrategy":"retry","validationCode":"# No deterministic pre-check exists; ensure connections are clean before release by\n# fully reading every response:\nassert not conn.can_read(), 'returning a connection with unread data'\n# (Call this in debug builds / pool release hooks.)","typeGuard":null,"tryCatchPattern":"import time\nfrom redis.exceptions import ConnectionError\n\nfor attempt in range(4):\n    try:\n        return r.get('key')\n    except ConnectionError as e:\n        if 'Connection not ready' in str(e) and attempt < 3:\n            time.sleep(0.1 * (2 ** attempt))\n            continue\n        raise","preventionTips":["Always fully consume command responses before returning connections to the pool.","Use the high-level Redis client so the pool manages release cleanly.","Treat 'Connection not ready' as transient and retry with backoff."],"tags":["connection","network","pool","transient"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}