Ioredis: ReplyError: ERR invalid DB index

Created on 16 Jun 2015  路  5Comments  路  Source: luin/ioredis

When using ioredis in Heroku using RedisToGo add-on, I get this error:

Unhandled rejection ReplyError: ERR invalid DB index 
    at ReplyParser._parseResult (/app/node_modules/ioredis/lib/parsers/javascript.js:56:14) 
    at ReplyParser.execute (/app/node_modules/ioredis/lib/parsers/javascript.js:174:20) 
    at Socket.<anonymous> (/app/node_modules/ioredis/lib/redis/event_handler.js:88:22) 
    at Socket.emit (events.js:107:17) 
    at readableAddChunk (_stream_readable.js:163:16) 
    at Socket.Readable.push (_stream_readable.js:126:10) 
    at TCP.onread (net.js:538:20) 

Everything works fine on my local machine(OS X) and local redis. I'm testing this with free plan in RedisToGo.

I'm initializing ioredis(version 1.5.0) like this:

        var redis = new Redis(process.env.REDIS_URL, {
            retryStrategy: function(times) {
                // Make reconnecting a bit more relaxed compared to default
                var delay = Math.min(times * 100, 4000);
                return delay;
            }
        });
  • REDIS_URL in heroku is in format: redis://redistogo:<secret>@<secret>.redistogo.com:<port>/.
  • REDIS_URL in local is: redis://127.0.0.1:6379

Do you have ideas of how to fix this? Redis works apparently correctly but my logs fill up with those exceptions and in general I'd like to get this resolved.

Most helpful comment

By setting the database to 0 in the url: redis://redistogo:<secret>@<secret>.redistogo.com:<port>/0 the issue goes away.

All 5 comments

By setting the database to 0 in the url: redis://redistogo:<secret>@<secret>.redistogo.com:<port>/0 the issue goes away.

This might be an bug in parsing urls with trailing slash. Quote from RedisToGo support:

Just wanted to send you a bit more information, as I did some digging into the driver code and I have found the source of the issue. Here is some sample code from the node shell that should explain things:

var urllib = require('url');
var Redis = require('ioredis');

// Explicit database 0
> var redis = Redis('redis://redistogo:[email protected]:54321/0');
undefined
> redis.get('foo', function(err, result){console.log(result);});
{ _bitField: 1,
  _fulfillmentHandler0: [Function: successAdapter],
  _rejectionHandler0: [Function: errorAdapter],
  _progressHandler0: undefined,
  _promise0: [Function],
  _receiver0: [Circular],
  _settledValue: undefined }
> bar

// Implied database 0
> var redis2 = Redis('redis://redistogo:[email protected]:54321');
undefined
> redis2.get('foo', function(err, result){console.log(result);});
{ _bitField: 1,
  _fulfillmentHandler0: [Function: successAdapter],
  _rejectionHandler0: [Function: errorAdapter],
  _progressHandler0: undefined,
  _promise0: [Function],
  _receiver0: [Circular],
  _settledValue: undefined }
> bar

// Force parse error
> var redis3 = Redis('redis://redistogo:[email protected]:54321/');
undefined
> Unhandled rejection ReplyError: ERR invalid DB index
    at ReplyParser._parseResult (/mycomputer/vault/code/node_realm/node_modules/ioredis/lib/parsers/javascript.js:56:14)
    at ReplyParser.execute (/mycomputer/vault/code/node_realm/node_modules/ioredis/lib/parsers/javascript.js:174:20)
    at Socket.<anonymous> (/mycomputer/vault/code/node_realm/node_modules/ioredis/lib/redis/event_handler.js:88:22)
    at Socket.emit (events.js:107:17)
    at readableAddChunk (_stream_readable.js:163:16)
    at Socket.Readable.push (_stream_readable.js:126:10)
    at TCP.onread (net.js:538:20)
> redis3.get('foo', function(err, result){console.log(result);});
{ _bitField: 1,
  _fulfillmentHandler0: [Function: successAdapter],
  _rejectionHandler0: [Function: errorAdapter],
  _progressHandler0: undefined,
  _promise0: [Function],
  _receiver0: [Circular],
  _settledValue: undefined }
> bar

// Different parsed URLs
> var p = url.parse('redis://redistogo:[email protected]:54321/0');
undefined
> p
{ protocol: 'redis:',
  slashes: true,
  auth: 'redistogo:mypassword',
  host: 'myhost.redistogo.com:54321',
  port: '54321',
  hostname: 'myhost.redistogo.com',
  hash: null,
  search: null,
  query: null,
  pathname: '/0',
  path: '/0',
  href: 'redis://redistogo:[email protected]:54321/0' }
> p.pathname.slice(1)
0

> var p2 = url.parse('redis://redistogo:[email protected]:54321');
undefined
> p2
{ protocol: 'redis:',
  slashes: true,
  auth: 'redistogo:mypassword',
  host: 'myhost.redistogo.com:54321',
  port: '54321',
  hostname: 'myhost.redistogo.com',
  hash: null,
  search: null,
  query: null,
  pathname: null,
  path: null,
  href: 'redis://redistogo:[email protected]:54321' }
// p2.pathname is null, won't call .split(1) and _.defaults will be called
// See code below
// https://github.com/luin/ioredis/blob/master/lib/utils/index.js#L254-L285

> var p3 = url.parse('redis://redistogo:[email protected]:54321/');
undefined
> p3
{ protocol: 'redis:',
  slashes: true,
  auth: 'redistogo:mypassword',
  host: 'myhost.redistogo.com:54321',
  port: '54321',
  hostname: 'myhost.redistogo.com',
  hash: null,
  search: null,
  query: null,
  pathname: '/',
  path: '/',
  href: 'redis://redistogo:[email protected]:54321/' }
> p3.pathname.slice(1)
''

Looking through the documentation for the driver they list a trailing slash as a valid URL, but in this driver it is not handled correctly. Here is the example in the docs:

https://github.com/luin/ioredis/blob/master/lib/redis.js#L84

My proposed solution would be to modify this code:

https://github.com/luin/ioredis/blob/master/lib/utils/index.js#L270-L272

if (parsed.protocol === 'redis:') {
    result.db = (parsed.pathname !== '/')
      ? parsed.pathname.slice(1)
      : '0';
}

I hope this helps explain things but please let me know if you have any further questions.

Thank you,
~John Moore
RedisToGo Support

Any idea what Version of Redis they're running at redistogo.com?
SELECT '' seems to be valid on >Redis 2.4 and defaults to 0.

It's a bug that getting a NaN db when the pathname is empty. Fixed in 1.5.1. Thanks for pointing it out.

This still happens on Heroku using v4.16.3. Adding /0 to the end of the Redis URL makes it go away.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

haoxins picture haoxins  路  5Comments

luckyscript picture luckyscript  路  5Comments

ORESoftware picture ORESoftware  路  5Comments

AdriVanHoudt picture AdriVanHoudt  路  4Comments

hzxuzhonghu picture hzxuzhonghu  路  5Comments