Redis Error Guide: 'SELECT is not allowed in cluster mode' — Drop Multiple Databases for Cluster
Fix SELECT is not allowed in cluster mode in Redis: understand why cluster uses only DB 0 and migrate code off numbered databases to key prefixes instead.
- #redis
- #database
- #troubleshooting
- #errors
Stuck on this Redis error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
Redis returns this error when a client sends SELECT <n> (to switch logical databases) against a server running in Redis Cluster mode. Standalone Redis offers 16 numbered logical databases (0–15) selectable with SELECT; Redis Cluster supports only database 0, so SELECT to any non-zero database is rejected.
The literal error clients receive:
(error) ERR SELECT is not allowed in cluster mode
This is by design. Cluster partitions the keyspace across nodes by hash slot, and multiple logical databases don’t fit that model, so the feature is disabled entirely. The error means application code (or a client library default) still assumes numbered databases that no longer exist once you move to cluster mode. The fix is to stop using SELECT and separate data by key prefix or by separate clusters/instances.
Symptoms
- Any
SELECT <n>withn != 0fails withSELECT is not allowed in cluster mode. - Code that worked on standalone Redis breaks immediately after migrating to a cluster.
- A client library configured with a non-zero
dbindex throws at connection time.
redis-cli -c SELECT 3
(error) ERR SELECT is not allowed in cluster mode
redis-cli CLUSTER INFO | grep cluster_enabled
cluster_enabled:1
Common Root Causes
1. App uses numbered databases for separation
The application isolated concerns (sessions in db 1, cache in db 2, queues in db 3) using SELECT, a pattern that cannot carry over to cluster.
2. Client library configured with a non-zero db
A connection string or config specifies db=1 (or /1 in a URL), and the client issues SELECT 1 on connect.
# e.g. redis://host:6379/1 -> triggers SELECT 1 on connect
3. A migration from standalone to cluster
Standalone code assumed 16 databases; after cutover to cluster mode every non-zero SELECT fails.
4. Tooling that defaults to a specific db
A migration or admin tool hard-codes SELECT to a numbered db.
Diagnostic Workflow
Step 1: Confirm the server is in cluster mode
redis-cli CLUSTER INFO | grep cluster_enabled
redis-cli INFO server | grep redis_mode
cluster_enabled:1 / redis_mode:cluster confirms only db 0 is available.
Step 2: Find where SELECT is being sent
# Search the app/config for numbered databases
grep -REn 'SELECT [1-9]|"db"|db=|redis://[^ ]*/[1-9]' ./src ./config 2>/dev/null | head
Connection URLs ending in /1../15 are a common hidden source.
Step 3: Inventory what lived in each database
Before cluster, list what each db held so you can re-map it to a prefix scheme.
# On the old standalone instance
redis-cli -n 1 DBSIZE
redis-cli -n 2 DBSIZE
Step 4: Design the replacement
Replace SELECT n with a key prefix (sess:, cache:, queue:) in the single db 0, or route each dataset to a separate cluster/instance if isolation must be physical.
Step 5: Read the logs
sudo journalctl -u redis-server --no-pager | grep -iE 'SELECT|cluster mode' | tail
Example Root Cause Analysis
A team migrates a standalone Redis to a three-shard cluster. Immediately the session service fails with ERR SELECT is not allowed in cluster mode. Its connection URL was redis://redis:6379/1 — the client issued SELECT 1 on every connect, isolating sessions in database 1.
redis-cli -c CLUSTER INFO | grep cluster_enabled
cluster_enabled:1
Cluster mode supports only db 0, so the /1 in the URL is invalid. The fix was to drop the numbered database and namespace the keys with a prefix in db 0 instead, so the data is still logically separated without relying on SELECT:
# Before: redis://redis:6379/1 with keys like user:42
# After: redis://redis-cluster:6379/0 (or no /db) with keys like sess:user:42
# keys now carry an explicit namespace prefix in db 0
redis-cli -c SET sess:user:42 '<token>' EX 1800
redis-cli -c GET sess:user:42
Because sessions, cache, and queues each got a distinct prefix, they coexist safely in db 0 across the cluster. Where two of those datasets needed physical isolation (different scaling/eviction), they were moved to separate clusters rather than separate databases.
Prevention Best Practices
- Design for a single database (db 0) from the start if cluster is on the roadmap; use key prefixes for logical separation instead of
SELECT. - Audit connection strings for a trailing
/1../15db index before migrating to cluster — these silently emitSELECT. - When datasets need real isolation (independent scaling, eviction, or blast radius), use separate clusters/instances, not numbered databases.
- Update client library configs to
db=0(or omit it) for cluster endpoints. - Establish a namespace convention (
{prefix}:{entity}:{id}) so prefix-based separation stays consistent and cluster-safe. - Feed cluster migration errors into the free incident assistant, and browse more Redis guides.
Quick Command Reference
# Confirm cluster mode (only db 0 exists)
redis-cli CLUSTER INFO | grep cluster_enabled
redis-cli INFO server | grep redis_mode
# Find SELECT usage and db-indexed URLs
grep -REn 'SELECT [1-9]|redis://[^ ]*/[1-9]|db=' ./src ./config
# Inventory old databases before migrating (standalone)
redis-cli -n 1 DBSIZE
redis-cli -n 2 DBSIZE
# Prefix-based separation in db 0 (cluster-safe)
redis-cli -c SET sess:user:42 '<token>' EX 1800
Conclusion
SELECT is not allowed in cluster mode means code tried to switch to a non-zero logical database on a cluster, which supports only db 0. The typical root causes are:
- An app that used numbered databases to separate concerns.
- A client library or connection URL configured with a non-zero db index.
- A migration from standalone to cluster where that assumption broke.
The fix is to stop using SELECT: separate datasets by key prefix within db 0, or give truly independent datasets their own cluster/instance. Audit connection strings for a trailing /n db index before any cluster migration, since that is the most common hidden trigger.
Fixed it? Get 500 Redis & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.