{"record":{"id":"eaeb78b65952bc96","repo":"redis/redis-py","slug":"no-connection-available-eaeb78","errorCode":null,"errorMessage":"No connection available.","messagePattern":"No connection available\\.","errorType":"exception","errorClass":"ConnectionError","httpStatus":null,"severity":"error","filePath":"redis/connection.py","lineNumber":3714,"sourceCode":"        \"\"\"\n        start_time_acquired = time.monotonic()\n        # Make sure we haven't changed process.\n        self._checkpid()\n        is_created = False\n\n        # Try and get a connection from the pool. If one isn't available within\n        # self.timeout then raise a ``ConnectionError``.\n        connection = None\n        try:\n            if self._in_maintenance:\n                self._lock.acquire()\n                self._locked = True\n            try:\n                connection = self.pool.get(block=True, timeout=self.timeout)\n            except Empty:\n                # Note that this is not caught by the redis client and will be\n                # raised unless handled by application code. If you want never to\n                raise ConnectionError(\"No connection available.\")\n\n            # If the ``connection`` is actually ``None`` then that's a cue to make\n            # a new connection to add to the pool.\n            if connection is None:\n                # Start timing for observability\n                start_time_created = time.monotonic()\n                connection = self.make_connection()\n                is_created = True\n        finally:\n            if self._locked:\n                try:\n                    self._lock.release()\n                except Exception:\n                    pass\n                self._locked = False\n\n        # Record state transition: IDLE -> USED\n        # (make_connection already recorded IDLE +1 for new connections)","sourceCodeStart":3696,"sourceCodeEnd":3732,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/connection.py#L3696-L3732","documentation":"Raised as ConnectionError('No connection available.') by BlockingConnectionPool.get_connection when the underlying Queue.get(block=True, timeout=self.timeout) raises Empty — i.e. no connection became available within the configured timeout. BlockingConnectionPool uses a bounded queue and waits up to self.timeout seconds before giving up; unlike the default pool it does not error immediately at the cap, but it does error if nothing frees up in time.","triggerScenarios":"All max_connections of a BlockingConnectionPool are checked out longer than self.timeout (default DEFAULT_TIMEOUT=20s). Connection leaks, long-running blocking commands, or saturated pubsub listeners holding all slots.","commonSituations":"Blocking commands (BLPOP, BRPOP, WAIT, MONITOR) tying up every connection. Thread/async fan-out exceeding pool size. Leaked connections never released. timeout set too low for the workload.","solutions":["Increase max_connections or self.timeout to match expected hold times.","Fix connection leaks — always return connections; prefer the high-level Redis client which manages release for you.","Cap concurrency (thread/async pool size) to stay within the Redis pool size.","Shorten or remove long-running blocking commands, or dedicate a separate pool/client for pubsub and blocking calls."],"exampleFix":"# before\npool = BlockingConnectionPool(max_connections=10, timeout=2)  # raises under load\n# after\npool = BlockingConnectionPool(max_connections=50, timeout=20)","handlingStrategy":"retry","validationCode":"# Pre-check: ensure expected concurrency <= pool size before relying on the pool.\nif expected_concurrent_ops > pool.max_connections:\n    raise RuntimeError(f'Concurrency {expected_concurrent_ops} exceeds pool size {pool.max_connections}; raise max_connections or reduce fan-out')","typeGuard":null,"tryCatchPattern":"import time\nfrom redis.exceptions import ConnectionError\n\nfor attempt in range(4):\n    try:\n        return r.get('key')\n    except ConnectionError as e:\n        if 'No connection available' in str(e) and attempt < 3:\n            time.sleep(0.2 * (2 ** attempt))\n            continue\n        raise  # raise so the caller can shed load or alert","preventionTips":["Tune max_connections and timeout to match worst-case hold times.","Fix connection leaks; let the high-level client manage release.","Bound your concurrency (thread/async pools) within the Redis pool size.","Move long-running blocking commands and pubsub to a dedicated pool."],"tags":["connection-pool","timeout","resource-limits","configuration"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}