redis/redis-py · error · ConnectionError

No connection available.

Error message

No connection available.

What it means

Raised as a ConnectionError by BlockingConnectionPool.get_connection (connection.py:3690-3699) when the internal queue.get(block=True, timeout=self.timeout) raises Empty — i.e. no connection became available within the configured timeout (default 20s). Unlike the non-blocking pool's immediate MaxConnectionsError, BlockingConnectionPool waits, and this error means the wait elapsed with nothing freed.

Source

Thrown at redis/connection.py:3699

        """
        start_time_acquired = time.monotonic()
        # Make sure we haven't changed process.
        self._checkpid()
        is_created = False

        # Try and get a connection from the pool. If one isn't available within
        # self.timeout then raise a ``ConnectionError``.
        connection = None
        try:
            if self._in_maintenance:
                self._lock.acquire()
                self._locked = True
            try:
                connection = self.pool.get(block=True, timeout=self.timeout)
            except Empty:
                # Note that this is not caught by the redis client and will be
                # raised unless handled by application code. If you want never to
                raise ConnectionError("No connection available.")

            # If the ``connection`` is actually ``None`` then that's a cue to make
            # a new connection to add to the pool.
            if connection is None:
                # Start timing for observability
                start_time_created = time.monotonic()
                connection = self.make_connection()
                is_created = True
        finally:
            if self._locked:
                try:
                    self._lock.release()
                except Exception:
                    pass
                self._locked = False

        # Record state transition: IDLE -> USED
        # (make_connection already recorded IDLE +1 for new connections)

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Increase the BlockingConnectionPool timeout (timeout=60) or set timeout=None to block indefinitely if you prefer waiting over failing.
  2. Raise max_connections to match peak concurrency.
  3. Fix connection leaks and avoid holding connections across long blocking commands.
  4. Catch ConnectionError around get_connection/pipeline and apply a retry/backoff for transient exhaustion.

Example fix

# before
pool = redis.BlockingConnectionPool(max_connections=10, timeout=2)
# raises ConnectionError: No connection available. under load

# after
pool = redis.BlockingConnectionPool(max_connections=50, timeout=30)
# or block forever
pool = redis.BlockingConnectionPool(max_connections=50, timeout=None)
Defensive patterns

Strategy: retry

Validate before calling

def blocking_pool(peak_concurrency: int, wait_s: float = 30.0) -> redis.BlockingConnectionPool:
    return redis.BlockingConnectionPool(
        max_connections=max(peak_concurrency, 50), timeout=wait_s)

client = redis.Redis(connection_pool=blocking_pool(my_thread_count))

Try / catch

from redis.exceptions import ConnectionError
for _ in range(3):
    try:
        return client.get("k")
    except ConnectionError as e:
        if "No connection available" in str(e):
            time.sleep(0.5)
            continue
        raise
raise

Prevention

When it happens

Trigger: Using BlockingConnectionPool and exhausting all connections for longer than `timeout` seconds: every connection is checked out (e.g. stuck in slow/blocking commands or leaked) and none is returned before the deadline.

Common situations: Long-running blocking commands (BLPOP, WAIT, MONITOR) holding connections; connection leaks; timeout set too low for realistic operation latency; a stall/deadlock where threads hold connections and block waiting for connections held by other threads.

Related errors


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