redis/redis-py · error · ConnectionError

Connection not ready

Error message

Connection not ready

What it means

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.

Source

Thrown at redis/connection.py:3294

            # 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,
                duration_seconds=time.monotonic() - start_time_created,
            )

        return connection

    def get_encoder(self) -> Encoder:
        "Return an encoder based on encoding settings"
        kwargs = self.connection_kwargs
        return Encoder(

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. 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.
  2. Switch to RESP3 with a proper push handler if the server is sending push messages.
  3. Investigate intermediaries (proxies, load balancers) that may be injecting data; test with a direct connection.
  4. As a workaround, recreate the pool; if it recurs, the server is genuinely pushing data the client must handle.

Example fix

# before
client = redis.Redis(connection_pool=pool)  # keyspace notifications enabled server-side

# after (consume the pushes via keyspace notifications API)
p = client.pubsub()
p.psubscribe("__keyevent@0__:*")
# drain in a loop, or use client.keyspace_notifications helpers
Defensive patterns

Strategy: try-catch

Try / catch

from redis.exceptions import ConnectionError
for _ in range(3):
    try:
        return client.get("k")
    except ConnectionError as e:
        if "not ready" in str(e).lower():
            # pool will rebuild; back off and retry
            time.sleep(0.1)
            continue
        raise
raise

Prevention

When it happens

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

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

Related errors


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