redis/redis-py · critical · NoValidDatabaseException

Initial connection failed - no active database found

Error message

Initial connection failed - no active database found

What it means

Raised as NoValidDatabaseException by MultiDBClient.initialize() (client.py:127) after the initial health check runs and no database ends up with a CLOSED circuit breaker. The client iterates self._databases looking for at least one CLOSED circuit to promote to active; if none qualifies, it cannot route any command and aborts startup.

Solutions

  1. Verify each configured database endpoint is reachable (redis-cli PING) and credentials/TLS are correct.
  2. Wait for Redis to be healthy before constructing the client (readiness probe / retry on NoValidDatabaseException).
  3. Loosen the initial_health_check_policy to ONE_AVAILABLE if business logic tolerates a partially-available fleet.
  4. Check that config.databases() returns the expected DatabaseConfig entries.

Example fix

# before
client = MultiDBClient(config)
client.execute_command('GET', 'k')  # initialize() raises

# after
import time
for attempt in range(30):
    try:
        client = MultiDBClient(config)
        client.initialize()
        break
    except NoValidDatabaseException:
        time.sleep(2)
else:
    raise RuntimeError('Redis fleet never became healthy')
Defensive patterns

Strategy: retry

Validate before calling

# Pre-flight: confirm at least one endpoint is reachable before constructing the client
import socket
from redis.config import DatabaseConfig  # adjust import to your config module

def any_reachable(configs) -> bool:
    for c in configs:
        host, port = getattr(c, 'host', None), getattr(c, 'port', None)
        if host and port:
            try:
                with socket.create_connection((host, port), timeout=2):
                    return True
            except OSError:
                continue
    return False

Type guard

from redis.multidb.client import MultiDBClient

def has_active_database(client: MultiDBClient) -> bool:
    """True when at least one database circuit is CLOSED."""
    return any(db.circuit.state.name == 'CLOSED' for db, _ in client.get_databases())

Try / catch

from redis.multidb.exception import NoValidDatabaseException
import time

for attempt in range(30):
    try:
        client = MultiDBClient(config)
        client.initialize()
        break
    except NoValidDatabaseException:
        time.sleep(2)
else:
    raise RuntimeError('no database became healthy in time')

Prevention

When it happens

Trigger: Constructing MultiDBClient(config) where every configured database fails its initial health check (network unreachable, auth failed, wrong host/port); all circuits transition to OPEN during _perform_initial_health_check; an empty databases list.

Common situations: All Redis endpoints down or misconfigured at app boot; wrong host/port in DatabaseConfig; network partition blocking every endpoint; credentials/TLS misconfigured across the board; CI starting the client before Redis containers are ready.

Related errors


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

Appendix: source

Thrown at redis/multidb/client.py:127

            self._health_check_interval,
            self._check_databases_health,
        )

        is_active_db_found = False

        for database, weight in self._databases:
            # Set on state changed callback for each circuit.
            database.circuit.on_state_changed(self._on_circuit_state_change_callback)

            # Set states according to a weights and circuit state
            if database.circuit.state == CBState.CLOSED and not is_active_db_found:
                # Directly set the active database during initialization
                # without recording a geo failover metric
                self.command_executor._active_database = database
                is_active_db_found = True

        if not is_active_db_found:
            raise NoValidDatabaseException(
                "Initial connection failed - no active database found"
            )

        self.initialized = True

    def get_databases(self) -> Databases:
        """
        Returns a sorted (by weight) list of all databases.
        """
        return self._databases

    def set_active_database(self, database: SyncDatabase) -> None:
        """
        Promote one of the existing databases to become an active.
        """
        exists = None

        for existing_db, _ in self._databases:

View on GitHub (pinned to 6a6b581b48)