Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild
Back to Blog Troubleshooting

Redis ERR DB index is out of range: What the Error Means, the Three Places It Comes From, and the Fix for Each

Sean

Platform Writer

Sep 15, 2026
8 min read

ERR DB index is out of range means your client sent SELECT with a database number the Redis server does not have. A default server has sixteen logical databases, numbered 0 to 15; a managed or clustered Redis usually has one, numbered 0. The number almost always arrives from a connection URL ending in a slash and a digit, or a db option in the client config. The fix is to use database 0, or to raise the databases setting if you control the server; the better fix is to stop using numbered databases at all and prefix keys instead.

Redis ERR DB index is out of range: What the Error Means, the Three Places It Comes From, and the Fix for Each

This error is one line long and the reports of it are scattered across a dozen client libraries, a forum thread about a managed Redis, a container image issue and a Terraform Enterprise support page. They are all the same problem. This post puts the cause in one place, then the fix for each of the three ways the bad number gets into your client.

Table of contents

What the error actually says

Redis has a feature most people never use: logical databases. A single server holds several independent keyspaces, numbered from zero, and a client picks one with SELECT n. The count is set by the databases directive in redis.conf and defaults to 16.

ERR DB index is out of range is the server’s reply to SELECT n when n is greater than or equal to that count. Ask for database 1 on a server configured with databases 1, and you get the error, because the only valid index is 0.

The confusing part is that you probably did not write SELECT anywhere. Client libraries send it for you on connect, whenever the connection details include a database number. So the error surfaces as a connection failure in whatever library you use:

ioredis:   [ioredis] Unhandled error event: ReplyError: ERR DB index is out of range
redis-py:  redis.exceptions.ResponseError: DB index is out of range
predis:    `SELECT` failed: ERR DB index is out of range
redis-rb:  Redis::CommandError: ERR DB index is out of range

Same server reply, four wrappers. The question is where the number came from.

Cause one: the connection URL ends in a database number

The Redis URL scheme puts the database number in the path: redis://host:6379/2 means connect and then SELECT 2. This is the most common source of the error, and it is common because the number is easy to miss at the end of a long string.

redis://default:[email protected]:6379/1
                                          ^ this is SELECT 1

Where it comes from in practice: a .env copied from another project, a framework’s example config, a docker-compose file that used /1 to keep cache and sessions apart, or a default in an application that assumes a local Redis with sixteen databases. Move that application to a managed Redis with one database and the first connection fails.

The fix is to drop the suffix or set it to /0:

redis://default:[email protected]:6379/0

Then search the codebase for the same number in other forms. Laravel has REDIS_DB and REDIS_CACHE_DB; Django’s cache config takes a db key; Rails and Sidekiq take db: in their Redis config. Any of them will send the SELECT even if the URL is clean.

Cause two: the server is configured with fewer databases

If you run Redis yourself and the URL says /1, /2 or /5 on purpose, check the server side. The databases directive may have been lowered, or the image you deployed sets it.

redis-cli -h redis.internal CONFIG GET databases
# 1) "databases"
# 2) "1"

If that returns something smaller than the index you want, either raise it or stop wanting it. Raising it is a config change and a restart:

# redis.conf
databases 16

CONFIG SET databases is not supported at runtime, so this is a restart, not a live change. In a container, it is a flag on the command line or a mounted config file, and the n8n Docker Compose example shows the mounted-config pattern for a sidecar service.

Some builds are stricter still. Redis in cluster mode supports only database 0, and SELECT with any other number returns this error regardless of the databases setting. If you are on a Redis cluster, the fix is always cause three.

Cause three: a managed Redis only has database 0

Most managed Redis services, and every Redis cluster, expose one logical database. The reasons are practical: SELECT is per connection and does not work with connection pooling across databases, cluster mode does not support it, and several providers consider numbered databases a legacy feature. The result is a server where databases is effectively 1.

So an application that worked against a local Redis, a Docker Redis, or a VPS Redis breaks the day it points at the managed one, and the error looks like a credentials problem because it happens at connect time.

There is no server-side fix here; you do not control the setting. The application has to use database 0 and separate its concerns another way. The standard other way is a key prefix:

cache:user:42:profile
session:8f3a...
queue:emails

Every client library supports a prefix option, and most frameworks expose it as a config key: REDIS_PREFIX in Laravel, KEY_PREFIX in Django’s cache config, a namespace option in Sidekiq and in ioredis. Prefixes work everywhere, survive a move to cluster mode, and let one SCAN cache:* clear the cache without touching sessions, which numbered databases never made easy.

Set every database number in the app to 0, add the prefix, and the error is gone for good rather than until the next migration.

A diagnosis in three commands

Before changing anything, confirm which cause you have. It takes a minute.

# 1. What does the server allow?
redis-cli -u "$REDIS_URL" CONFIG GET databases

# 2. Does a plain connection work with database 0?
redis-cli -u "${REDIS_URL%/*}/0" PING
# PONG

# 3. What is the app actually sending?
redis-cli -u "${REDIS_URL%/*}/0" MONITOR | grep -i select

The third command watches live traffic and prints the SELECT the client sends on connect, with the number, which settles the argument about whether the URL or a config key is the source. Stop it with Ctrl-C; MONITOR is expensive on a busy server and should not run for long. The redis-cli post covers -u and the other connection flags.

If CONFIG GET is refused, the provider has disabled it, which is itself the answer: you are on a managed instance, and cause three applies.

Fixing it per client library

The change is the same everywhere, a database number set to 0 and a prefix added, but the config key differs.

ioredis / node-redis. Remove the db option or set it to 0; use keyPrefix in ioredis. The ioredis vs node-redis post covers the option names for both.

const redis = new Redis(process.env.REDIS_URL, { db: 0, keyPrefix: "app:" });

redis-py. Redis.from_url(url) reads the path; make sure it ends in /0 or has no path. There is no built-in prefix, so wrap keys with a helper or use a framework’s cache layer.

Laravel / predis / phpredis. Set REDIS_DB=0 and REDIS_CACHE_DB=0 in .env, and REDIS_PREFIX for the namespace. The cache connection is the one people miss, because it is a separate entry in config/database.php.

Rails / Sidekiq. Remove db: from the Redis config hash; Sidekiq takes a namespace: option for the prefix.

Django. In CACHES, the LOCATION URL should end in /0, and KEY_PREFIX sets the namespace.

Redeploy, watch the logs for the first connection, and run MONITOR for a few seconds to confirm no SELECT with a non-zero number is sent. Then leave it at 0 permanently: the numbered databases were never a good idea, and every managed Redis is telling you so.

How this fits the rest of the stack

ERR DB index is out of range is a SELECT for a database the server does not have, and it comes from a URL suffix, a config default, or a managed instance that only has database 0. Find the number with MONITOR, set it to 0, and separate concerns with key prefixes instead. RunxBuild does not offer a managed Redis, so the Redis in this setup is one you run or rent elsewhere; the application talking to it is still a Node, Python or Docker service with deploy logs where that first failed connection shows up, and the RunxBuild hosting calculator shows what that service and the managed Postgres beside it cost as separate line items.

Useful related references:

FAQ

What does ERR DB index is out of range mean in Redis?

The client sent SELECT with a database number the server does not have. Redis defaults to sixteen logical databases numbered 0 to 15, but managed instances and cluster mode typically have only database 0. The number usually comes from a connection URL ending in a slash and a digit, or a db option in the client configuration.

How do I fix DB index is out of range in ioredis?

Check the connection URL for a trailing /1 or similar and change it to /0 or remove it, and remove or zero any db option passed to the Redis constructor. Use the keyPrefix option to separate concerns instead of numbered databases. Run redis-cli MONITOR briefly to confirm the client no longer sends SELECT with a non-zero number.

Why does my Redis only have one database?

Managed Redis services and Redis in cluster mode expose only database 0, because SELECT is per connection, does not work with pooling across databases, and is unsupported in cluster mode. If you run Redis yourself, the databases directive in redis.conf controls the count and may have been lowered in your image or config.

Can I change the number of Redis databases at runtime?

No. The databases directive is read at startup and CONFIG SET does not accept it. Change it in redis.conf or on the command line and restart the server. On a managed service you cannot change it at all, which is a reason to design the application around database 0 and key prefixes from the start.

Should I use Redis numbered databases at all?

Generally no. They do not work in cluster mode, most managed providers disable them, and they make connection pooling awkward. Key prefixes such as cache: and session: give the same separation, work everywhere, and let you clear one namespace with a SCAN pattern. Set every database number to 0 and use prefixes.

#redis db index is out of range#redis select#redis databases#ioredis error#redis connection error