redis/redis-py · error · ConnectionError

Connection has data

Error message

Connection has data

What it means

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.

Source

Thrown at redis/connection.py:3285

            pool_name=pool_name,
            connection_state=ConnectionState.USED,
            counter=1,
        )

        try:
            # ensure this connection is connected to Redis
            connection.connect()
            # connections that the pool provides should be ready to send
            # a command. if not, the connection was either returned to the
            # pool before all data has been read or the socket has been
            # closed. either way, reconnect and verify everything is good.
            try:
                if (
                    connection.can_read()
                    and self.cache is None
                    and not self.maint_notifications_enabled()
                ):
                    raise ConnectionError("Connection has data")
            except (ConnectionError, TimeoutError, OSError):
                connection.disconnect()
                connection.connect()
                if (
                    connection.can_read()
                    and self.cache is None
                    and not self.maint_notifications_enabled()
                ):
                    raise ConnectionError("Connection not ready")
        except BaseException:
            # release the connection back to the pool so that we don't
            # leak it
            self.release(connection)
            raise

        if is_created:
            record_connection_create_time(
                connection_pool=self,

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. 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.
  2. Ensure connections are not shared across threads/coroutines concurrently.
  3. If using pipelines/transactions, ensure you read the full response before the connection is released.
  4. 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.

Example fix

# before (raw conn, response not read before release)
conn = pool.get_connection("GET")
conn.send_command("GET", "k")
# exception skips read_response; conn returned to pool with data

# after (always read, or use the client API)
client = redis.Redis(connection_pool=pool)
client.get("k")  # client guarantees send+read pairing
Defensive patterns

Strategy: retry

Validate before calling

def healthy_connection(pool):
    for _ in range(3):
        conn = pool.get_connection("PING")
        try:
            conn.send_command("PING")
            conn.read_response()
            return conn
        except Exception:
            pool.release(conn)
    raise RuntimeError("Could not obtain a clean connection")

Try / catch

from redis.exceptions import ConnectionError
for _ in range(3):
    try:
        return client.get("k")
    except ConnectionError as e:
        if "Connection has data" in str(e):
            continue
        raise
raise ConnectionError("connection repeatedly had leftover data")

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/0349d90af1d02486.json. Report an issue: GitHub.