{"id":"0349d90af1d02486","repo":"redis/redis-py","slug":"connection-has-data-0349d9","errorCode":null,"errorMessage":"Connection has data","messagePattern":"Connection has data","errorType":"exception","errorClass":"ConnectionError","httpStatus":null,"severity":"error","filePath":"redis/connection.py","lineNumber":3285,"sourceCode":"            pool_name=pool_name,\n            connection_state=ConnectionState.USED,\n            counter=1,\n        )\n\n        try:\n            # ensure this connection is connected to Redis\n            connection.connect()\n            # connections that the pool provides should be ready to send\n            # 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,","sourceCodeStart":3267,"sourceCodeEnd":3303,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/connection.py#L3267-L3303","documentation":"Raised as a ConnectionError by ConnectionPool.get_connection (connection.py:3280-3285) when a pooled connection handed back to a caller has unread bytes on its socket (connection.can_read() is True), and neither client-side caching nor maintenance notifications are active (those legitimately push unsolicited data). It indicates a previous command's response was not fully consumed before the connection was returned to the pool.","triggerScenarios":"Returning a connection to the (default, non-blocking) ConnectionPool without having read its full response — e.g. abandoning a pipeline read, an exception between send and read, or a multi/exec left half-read. The next get_connection detects leftover data and raises to avoid corrupting the next command.","commonSituations":"Bugs where a caller sends a command but skips read_response on an error path; mixing raw connection use with the client; server pushing data the client didn't expect over RESP2; incorrectly shared connection across coroutines/threads without synchronization.","solutions":["Always pair every send_command with a read_response, even on error paths; use the high-level client/pipeline API which guarantees this rather than raw connections.","Ensure connections are not shared across threads/coroutines concurrently.","If using pipelines/transactions, ensure you read the full response before the connection is released.","The pool will attempt a disconnect+reconnect (see error 417 path); a clean recovery is to let the pool replace the connection and retry the operation."],"exampleFix":"# before (raw conn, response not read before release)\nconn = pool.get_connection(\"GET\")\nconn.send_command(\"GET\", \"k\")\n# exception skips read_response; conn returned to pool with data\n\n# after (always read, or use the client API)\nclient = redis.Redis(connection_pool=pool)\nclient.get(\"k\")  # client guarantees send+read pairing","handlingStrategy":"retry","validationCode":"def healthy_connection(pool):\n    for _ in range(3):\n        conn = pool.get_connection(\"PING\")\n        try:\n            conn.send_command(\"PING\")\n            conn.read_response()\n            return conn\n        except Exception:\n            pool.release(conn)\n    raise RuntimeError(\"Could not obtain a clean connection\")","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 \"Connection has data\" in str(e):\n            continue\n        raise\nraise ConnectionError(\"connection repeatedly had leftover data\")","preventionTips":["Use the high-level redis.Redis client API, which guarantees send/read pairing and proper release.","Never skip read_response after send_command, even on error paths.","Avoid sharing a single raw connection across concurrent threads/coroutines."],"tags":["connection-pool","connection","protocol","debugging"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}