redis/redis-py · warning · ConnectionError

Connection not ready

Error message

Connection not ready

What it means

Raised by ensure_connection() after the pool already detected unread data ([128]), disconnected, reconnected, and STILL finds data on the socket. This means even a fresh connection is not clean, indicating a deeper socket/transport problem rather than a one-off half-read. The second check at connection.py:2877 trips.

Source

Thrown at redis/asyncio/connection.py:2878

        # Note: We don't record IDLE here because async uses a sync make_connection
        # but async record_connection_count. The recording is handled in get_connection.
        return self.connection_class(**self.connection_kwargs)

    async def ensure_connection(self, connection: AbstractConnection):
        """Ensure that the connection object is connected and valid"""
        await 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 await connection.can_read() and not self.maint_notifications_enabled():
                raise ConnectionError("Connection has data") from None
        except (ConnectionError, TimeoutError, OSError):
            await connection.disconnect()
            await connection.connect()
            if await connection.can_read() and not self.maint_notifications_enabled():
                raise ConnectionError("Connection not ready") from None

    async def release(self, connection: AbstractConnection):
        """Releases the connection back to the pool"""
        # Connections should always be returned to the correct pool,
        # not doing so is an error that will cause an exception here.
        async with self._lock:
            self._in_use_connections.remove(connection)

            if connection.should_reconnect():
                await connection.disconnect()

            self._available_connections.append(connection)

        await self._event_dispatcher.dispatch_async(
            AsyncAfterConnectionReleasedEvent(connection)
        )

        # Record state transition: USED -> IDLE

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Verify nothing is pushing unsolicited data on the connection (disable server-pushed features, or enable maintenance notifications if the server is a managed Redis sending MOVING notices).
  2. Route around proxies/sidecars that may inject bytes and test against the Redis directly.
  3. Report with repro details if it happens with a direct connection and standard usage.

Example fix

// before
# non-maintenance pool receiving server-pushed maintenance frames
redis = Redis(host=..., port=...)
// after
redis = Redis(host=..., port=...,
             maint_notifications_config=MaintNotificationsConfig(enabled=True))
Defensive patterns

Strategy: try-catch

Validate before calling

# if the server is a managed Redis pushing maintenance frames, enable the feature
if server_is_managed and not redis.connection_pool.maint_notifications_enabled():
    await redis.connection_pool.update_maint_notifications_config(
        MaintNotificationsConfig(enabled=True))

Type guard

def pool_accepts_pushed_data(pool) -> bool:
    return pool.maint_notifications_enabled()

Try / catch

from redis.exceptions import ConnectionError
try:
    await pool.get_connection('GET')
except ConnectionError as e:
    if 'not ready' in str(e):
        # investigate unsolicited data source; test direct connection
        await pool.disconnect()

Prevention

When it happens

Trigger: ensure_connection reconnects a dirty connection and can_read() is True again after reconnect. The disconnect+connect cycle did not yield a quiescent socket.

Common situations: Persistent protocol desync; a proxy or intermediary (e.g., stunnel, a buggy sidecar) injecting data; server pushing unsolicited data on a non-maintenance-notifications connection; kernel/loopback buffering oddities.

Related errors


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