redis/redis-py · error · 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() (failover.py:114-121) when WeightBasedFailoverStrategy.database() raised NoValidDatabaseException but the failover retry budget (failover_attempts) has not yet been exhausted. It is the transient sibling of 154: the system believes databases may recover shortly and tells the caller to retry rather than failing hard.
Solutions
- Retry the operation with backoff — the message explicitly says this is temporary. Combine with command_retry tuning.
- Increase failover_attempts and/or failover_delay in MultiDbConfig to give circuits more time to recover before the hard NoValidDatabaseException.
- Reduce circuit reset_timeout/grace_period so circuits return to HALF_OPEN/CLOSED faster.
- Catch TemporaryUnavailableException separately from NoValidDatabaseException and apply a bounded retry with jitter; fail open to a cache/degraded path if exhausted.
- Investigate why all circuits are simultaneously open (shared failure domain).
Example fix
// before
resp = await client.get("k") # TemporaryUnavailableException bubbles up & crashes caller
// after
import asyncio
from redis.multidb.exception import TemporaryUnavailableException
for attempt in range(5):
try:
resp = await client.get("k"); break
except TemporaryUnavailableException:
await asyncio.sleep(0.2 * (2 ** attempt))
else:
resp = await cache.get("k") # degrade Defensive patterns
Strategy: retry
Validate before calling
from redis.multidb.circuit import State as CBState
def likely_temporary(client) -> bool:
# circuits are not all closed, but at least one is HALF_OPEN (recovering)
states = {d.circuit.state for d, _ in client.get_databases()}
return CBState.HALF_OPEN in states or CBState.OPEN in states
# if likely_temporary(client): retry with backoff instead of failing Type guard
from redis.multidb.circuit import State as CBState
def has_recovering_circuit(client) -> bool:
return any(d.circuit.state == CBState.HALF_OPEN for d, _ in client.get_databases()) Try / catch
import asyncio
from redis.multidb.exception import TemporaryUnavailableException, NoValidDatabaseException
async def call_with_retry(client, fn, *args, attempts=5, base=0.2):
for i in range(attempts):
try:
return await fn(client, *args)
except TemporaryUnavailableException:
await asyncio.sleep(base * (2 ** i))
# final attempt: let NoValidDatabaseException surface if circuits never recover
return await fn(client, *args) Prevention
- Catch TemporaryUnavailableException separately from NoValidDatabaseException and retry with jittered backoff.
- Tune failover_attempts/failover_delay to give circuits time to recover before the hard failure.
- Monitor TemporaryUnavailableException rate as an early-warning for cascading outages.
- Provide a bounded retry wrapper around command execution.
- Ensure circuits have a short reset_timeout so HALF_OPEN probes happen quickly.
When it happens
Trigger: Any command whose execution triggers _check_active_database() during a window where all circuits are OPEN/HALF_OPEN and the failover_counter is still <= failover_attempts (default 10, spaced by failover_delay default 12s). The exception propagates out of execute_command/execute_pipeline/execute_transaction.
Common situations: Brief total outages during a failover storm, all databases momentarily in HALF_OPEN awaiting their next probe, a rolling restart of every region, or network blips lasting on the order of failover_delay × failover_attempts.
Related errors
- No database connections currently available. This is a…
- No valid database available for communication
- Cannot set active database, database is unhealthy
- Cannot set active database, database is unhealthy
- Initial connection failed - no active database found
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/83ef0165fa1bed93.
Report an issue: GitHub.
Appendix: source
Thrown at redis/asyncio/multidb/failover.py:118
async def execute(self) -> AsyncDatabase:
try:
database = await 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)