redis/redis-py · error · ConnectionError
Invalid Database
Error message
Invalid Database
What it means
Raised as ConnectionError during on_connect() when SELECT <db> returns a non-OK reply, meaning the server refused the database switch. The library only sends SELECT when self.db is truthy (non-zero). The most frequent cause is requesting a database index that does not exist on the server.
Solutions
- Use db=0 (the only supported index on Redis Cluster and most managed providers).
- Raise CONFIG SET databases N / the 'databases' directive in redis.conf and restart, if you genuinely need a higher index on standalone Redis.
- Remove the /<db> path component from the connection URL.
- If sharding by db is required, switch to multiple client instances each pointing at db 0 on different deployments.
Example fix
// before
r = redis.asyncio.from_url('redis://host:6379/20')
// after
r = redis.asyncio.from_url('redis://host:6379/0') Defensive patterns
Strategy: validation
Validate before calling
def safe_db(db: int, max_databases: int = 16) -> int:
if db < 0 or db >= max_databases:
return 0
return db Type guard
from redis.exceptions import ConnectionError
def is_invalid_db(exc: BaseException) -> bool:
return isinstance(exc, ConnectionError) and 'invalid database' in str(exc).lower() Try / catch
from redis.exceptions import ConnectionError
try:
await client.select(db)
except ConnectionError as e:
if 'invalid database' in str(e).lower():
await client.select(0)
else:
raise Prevention
- Use db=0 with Redis Cluster and managed providers.
- Match CONFIG databases in redis.conf to the highest index you use.
- Strip /<db> from copied URLs when switching providers.
When it happens
Trigger: Constructing redis.asyncio.Redis(host=h, db=15) (or from_url('redis://host/15')) against a server configured with fewer than 16 databases, or a Redis Cluster target where SELECT to a non-zero db is not permitted.
Common situations: Default redis.conf databases=16 but user sets db=20; connecting to a managed Redis (cluster) that only allows db 0; leftover /N path in a copied URL pointing at an index the new provider does not have.
Related errors
- Error setting client name
- Invalid Username or Password
- Argument 'db' must be 0 or None in cluster mode
- Bad response from PING health check
- Buffer is closed.
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/fdb0f06f8c8f8a36.
Report an issue: GitHub.
Appendix: source
Thrown at redis/asyncio/connection.py:1064
self.driver_info.lib_version,
check_health=check_health,
)
lib_version_sent = True
# if a database is specified, switch to it. Also pipeline this
if self.db:
await self.send_command("SELECT", self.db, check_health=check_health)
# read responses from pipeline
for _ in range(sum([lib_name_sent, lib_version_sent])):
try:
await self.read_response()
except ResponseError:
pass
if self.db:
if str_if_bytes(await self.read_response()) != "OK":
raise ConnectionError("Invalid Database")
async def disconnect(
self,
nowait: bool = False,
error: Optional[Exception] = None,
failure_count: Optional[int] = None,
health_check_failed: bool = False,
) -> None:
"""Disconnects from the Redis server"""
# The server session is gone, so any HIMPORT fieldsets prepared on this
# socket no longer exist; reset the tracking.
self._reset_himport_state()
# On Python 3.13+, asyncio.timeout() raises RuntimeError when called
# outside a running Task (e.g. during GC finalization or event-loop
# callbacks). In that context we fall back to a synchronous close.
# See https://github.com/redis/redis-py/issues/3856
if asyncio.current_task() is None:
self._parser.on_disconnect()View on GitHub (pinned to 6a6b581b48)