{"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":3294,"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":3276,"sourceCodeEnd":3312,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/connection.py#L3276-L3312","documentation":"Raised as a ConnectionError by ConnectionPool.get_connection (connection.py:3289-3294) when, after detecting leftover data (error 416 path), the pool disconnects and reconnects the connection but connection.can_read() STILL returns True. This means even a fresh handshake sees unread data — a deeper socket/protocol problem rather than a one-off unread response.","triggerScenarios":"A pooled connection that, after disconnect()+connect(), immediately reports data available to read. Can happen with persistent server-side pushes the client isn't consuming, a half-closed socket, or a misbehaving proxy/intermediary that injects bytes after reconnect.","commonSituations":"Server-side keyspace notifications or push messages arriving on a connection the client isn't set up to consume (and CSC/maint notifications aren't enabled to absorb them); buggy network middleboxes; RESP3 push data on a connection not configured with a push handler.","solutions":["If you expect server pushes, enable the appropriate consumer (client-side caching cache_config, maintenance notifications, or a pubsub/keyspace-notifications handler) so pushes are consumed instead of treated as stray data.","Switch to RESP3 with a proper push handler if the server is sending push messages.","Investigate intermediaries (proxies, load balancers) that may be injecting data; test with a direct connection.","As a workaround, recreate the pool; if it recurs, the server is genuinely pushing data the client must handle."],"exampleFix":"# before\nclient = redis.Redis(connection_pool=pool)  # keyspace notifications enabled server-side\n\n# after (consume the pushes via keyspace notifications API)\np = client.pubsub()\np.psubscribe(\"__keyevent@0__:*\")\n# drain in a loop, or use client.keyspace_notifications helpers","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from redis.exceptions import ConnectionError\nfor _ in range(3):\n    try:\n        return client.get(\"k\")\n    except ConnectionError as e:\n        if \"not ready\" in str(e).lower():\n            # pool will rebuild; back off and retry\n            time.sleep(0.1)\n            continue\n        raise\nraise","preventionTips":["If you expect server pushes, enable a consumer (CSC, keyspace notifications, pubsub) so data is drained.","Use RESP3 with a configured push handler when the server sends push messages.","Test for intermediaries/proxies that inject bytes; prefer direct connections for diagnosis."],"tags":["connection-pool","connection","protocol","push-messages"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}