redis/redis-py · error · ConnectionError
Connection not ready
Error message
Connection not ready
What it means
Raised as ConnectionError('Connection not ready') by ConnectionPool.get_connection / the blocking pool after a connection that still had unread socket data was disconnected and reconnected and still reports can_read() True (and client-side caching and maintenance notifications are not active, which would legitimately leave push data on the socket). It indicates the reconnected socket is not in a clean command-ready state, so handing it out would corrupt the request/response framing.
Solutions
- Ensure every command's response is fully read before returning the connection to the pool (avoid partial reads in pipelines/transactions).
- Treat this as transient and retry the operation with backoff; the pool releases the bad connection on raise.
- If it recurs, enable client-side caching or maintenance notifications only where appropriate, or review for server push traffic the client isn't expecting.
Example fix
# before - response not fully consumed, conn returned dirty
pipe = r.pipeline()
pipe.set('a', 1)
pipe.execute() # partially read elsewhere -> next get_connection can raise
# after - always drain the response, and retry on transient ConnectionError
for attempt in range(3):
try:
return r.get('a')
except redis.exceptions.ConnectionError:
continue Defensive patterns
Strategy: retry
Validate before calling
# No deterministic pre-check exists; ensure connections are clean before release by # fully reading every response: assert not conn.can_read(), 'returning a connection with unread data' # (Call this in debug builds / pool release hooks.)
Try / catch
import time
from redis.exceptions import ConnectionError
for attempt in range(4):
try:
return r.get('key')
except ConnectionError as e:
if 'Connection not ready' in str(e) and attempt < 3:
time.sleep(0.1 * (2 ** attempt))
continue
raise Prevention
- Always fully consume command responses before returning connections to the pool.
- Use the high-level Redis client so the pool manages release cleanly.
- Treat 'Connection not ready' as transient and retry with backoff.
When it happens
Trigger: A pooled connection was returned with unread bytes (e.g. a previous command's reply not fully consumed, or an unsolicited server push), the pool disconnects/reconnects, and the fresh socket still shows pending data — typically due to a server-side push, a half-read pipeline reply, or a flaky network path.
Common situations: Not fully consuming responses (abandoned read_response). Server pushing data right after connect. Aggressive health-check or pubsub traffic on a non-cache, non-maintenance pool. Transient socket corruption.
Related errors
- Bad response from PING health check
- Connection closed by server.
- Connection closed by server.
- Connection closed by server.
- Connection closed by server.
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/fcf5eff9625f284e.
Report an issue: GitHub.
Appendix: source
Thrown at redis/connection.py:3309
# 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 6a6b581b48)