redis/redis-py · warning · TemporaryUnavailableException

No database connections currently available. This is a…

Error message

No database connections currently available. This is a temporary condition - please retry the operation.

What it means

Raised as TemporaryUnavailableException by DefaultFailoverStrategyExecutor.execute() (redis/multidb/failover.py:118) when the WeightBasedFailoverStrategy finds every database's circuit breaker in the OPEN state and the internal failover counter has not yet exceeded failover_attempts (default 10). It is intentionally non-fatal: the executor increments a counter and sets a retry deadline (default 12s) and tells the caller to retry. Once the counter exceeds failover_attempts, the original NoValidDatabaseException is raised instead, making this the transient variant of total failure.

Solutions

  1. Retry the operation with backoff — this exception is documented as temporary and the executor is already pacing retries internally; a caller-side retry loop with jitter is the intended response.
  2. Verify each database endpoint is reachable (host/port/credentials/TLS) and that health checks in redis/multidb/database.py are passing so breakers can transition OPEN -> CLOSED.
  3. Raise failover_attempts / failover_delay on DefaultFailoverStrategyExecutor if your upstream recovery legitimately takes longer than the default 10 attempts / 12s spacing.
  4. If persistent, inspect circuit breaker state and failure_detector config (redis/multidb/failure_detector.py, redis/multidb/config.py) to confirm thresholds are not too sensitive for your latency profile.
  5. Confirm at least one database is configured and healthy before traffic — a multidb client with zero CLOSED databases will always hit this path.

Example fix

// before
try {
    client.set('k', 'v')
} catch (e) {
    // any exception aborts the request
}

// after - retry transient multidb unavailability
for attempt in range(5):
    try:
        client.set('k', 'v')
        break
    except TemporaryUnavailableException:
        time.sleep(backoff_with_jitter(attempt))
Defensive patterns

Strategy: retry

Validate before calling

from redis.multidb.circuit import State as CBState

def has_closed_database(databases):
    # Run before issuing commands to confirm at least one breaker is CLOSED
    return any(db.circuit.state == CBState.CLOSED for db in databases)

Try / catch

from redis.multidb.exception import TemporaryUnavailableException

def call_with_retry(client, fn, *args, max_retries=5, base_delay=0.2, **kwargs):
    for attempt in range(max_retries):
        try:
            return fn(client, *args, **kwargs)
        except TemporaryUnavailableException:
            if attempt == max_retries - 1:
                raise
            time.sleep(base_delay * (2 ** attempt) + random.random() * base_delay)
    # loop exhausted
    raise TemporaryUnavailableException('exhausted retries')

Prevention

When it happens

Trigger: Any command issued through the multidb (Active-Active) client whose command_executor calls executor.execute() while ALL configured databases have circuit breakers in CBState.OPEN. Each database trips its breaker (via pybreaker in redis/multidb/circuit.py) after repeated failures, so a multi-region outage, a misconfigured endpoint, or a failure-detector storm leaves zero CLOSED databases and every execute() call returns this exception until a breaker resets or the 10-attempt cap is exceeded.

Common situations: All replica regions temporarily unreachable during a network partition; every endpoint misconfigured to the same wrong host/port so all breakers trip on first health-check batch; a failover-detector threshold (redis/multidb/failure_detector.py) set too aggressive causing cascading OPEN breakers under normal latency; startup before any database has passed its initial health check; TLS/auth rotated everywhere so every connection fails identically.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/66e59e1ed4b5fb14. Report an issue: GitHub.

Appendix: source

Thrown at redis/multidb/failover.py:118

    def execute(self) -> SyncDatabase:
        try:
            database = self._strategy.database()
            self._reset()
            return database
        except NoValidDatabaseException as e:
            if self._next_attempt_ts == 0:
                self._next_attempt_ts = time.time() + self._failover_delay
                self._failover_counter += 1
            elif time.time() >= self._next_attempt_ts:
                self._next_attempt_ts += self._failover_delay
                self._failover_counter += 1

            if self._failover_counter > self._failover_attempts:
                self._reset()
                raise e
            else:
                raise TemporaryUnavailableException(
                    "No database connections currently available. "
                    "This is a temporary condition - please retry the operation."
                )

    def _reset(self) -> None:
        self._next_attempt_ts = 0
        self._failover_counter = 0

View on GitHub (pinned to 6a6b581b48)