ioredis icon indicating copy to clipboard operation
ioredis copied to clipboard

ClusterAllFailedError: Failed to refresh slots cache.

Open achakhalyan opened this issue 5 years ago • 23 comments

Hi All. i have following error can You help me ? [ioredis] Unhandled error event: ClusterAllFailedError: Failed to refresh slots cache.

code is following. `"use strict"; require('./config/config'); const Redis = require('ioredis');

(async()=> {

const startupNodes = [
    {host: process.env.REDIS_HOST_1, port: process.env.REDIS_PORT },
    {host: process.env.REDIS_HOST_2, port: process.env.REDIS_PORT}
    ];
const options = {
    slotsRefreshTimeout: 2000,
    dnsLookup: (address, callback) => callback(null, address),
    redisOptions: {
        tls: {},
        password: process.env.REDIS_PASS,
    },
};
const cluster = new Redis.Cluster(startupNodes, options);
console.log(cluster);

})();`

achakhalyan avatar Nov 11 '19 14:11 achakhalyan

This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 7 days if no further activity occurs, but feel free to re-open a closed issue if needed.

stale[bot] avatar Dec 11 '19 15:12 stale[bot]

Have the same issue. Using an AWS elasticache redis (cluster mode enabled with multiple shards). I get the issue when using in-transit encryption and trying to access behind a NAT instance.

iocentos avatar Dec 17 '19 10:12 iocentos

Same issue here

Dartv avatar Dec 26 '19 19:12 Dartv

FWIW, I know this issue is re: clustered but I was fighting with this as well (in-transit encryption on, passworded redis) and this connection string finally got me going, I expect it'd work with a cluster as well:

const redis = new Redis({
  host: redisHost,
  port: redisPort,
  password: redisPassword,
  tls: {
    checkServerIdentity: (servername, cert) => {
      // skip certificate hostname validation
      return undefined;
    },
  },
});

peteclark3 avatar Jan 14 '20 21:01 peteclark3

Facing the same issue with 4.11.1 ioredis and redis 3.2.2

maknahar avatar Jan 17 '20 11:01 maknahar

any updates on this ?

bezzil85 avatar Feb 11 '20 09:02 bezzil85

~Same issue here, running latest code:~

ioredis @ 4.16.0 elasticache with engine @ 5.0.6

My particular issue was a result of an improperly deployed security group on the ElastiCache cluster, so it was truly unable to connect.

All seems to work ok with the above library versions!

jsmylnycky avatar Mar 09 '20 19:03 jsmylnycky

The following works for me.

Redis version: 5.0.4 on AWS ElasticCache Clustered with TLS and AUTH enabled. ioredis version: 4.16.0

Code to connect:

const redis = new Redis.Cluster(
            [{ "host": <ELASTI_CACHE_CONFIGURATION_ENDPOINT> }], {
                dnsLookup: (address, callback) => callback(null, address),
                redisOptions: {
                    tls: true,
                    password: <ELASTI_CACHE_REDIS_AUTH>
                }
            });

Make sure you are in the right VPC, Subnet and Security group to connect to ElastiCache along with the correct IAM role

GSSwain avatar Mar 14 '20 14:03 GSSwain

We're having a similar issue. Redis version: 5.0.4 on AWS ElasticCache Clustered (3 nodes, 1 shard) ioredis version: 4.16.0

Code to connect:

const Redis = require("ioredis");
var cluster = new Redis.Cluster([
  {
    host: <PRIMARY_RW_ENDPOINT>, port: 6379
  },
  {
   host: <SECONDARY_READERS_ENDPOINT>, port: 6379,
  }
], {
  dnsLookup: (address, callback) => callback(null, address),

  scaleReads: 'slave'
})

This code works, but bypasses the cluster for reads, if I understand it correctly:

const Redis = require("ioredis");
var cluster = new Redis({ host: <PRIMARY_RW_ENDPOINT>, port: 6379 })

I can also connect via redis-cli -h <PRIMARY_RW_ENDPOINT>, so I'm sure VPC, Subnet and Security groups are all correct.

ion-willo avatar Mar 18 '20 06:03 ion-willo

@ion-willo Is your ElastiCache cluster-mode-enabled? If so, I suggest you connect to the single configuration endpoint.

joebowbeer avatar Jun 26 '20 18:06 joebowbeer

Hi, I have the same issue using AWS ElastiCache & ioredis:

[ElastiCache] Configuration Endpoint: clustercfg.test1.xxxxxx.use2.cache.amazonaws.com:6379 Engine Version Compatibility: 5.0.6 Parameter Group: default.redis5.0.cluster.on (in-sync) Engine:Engine: Clustered Redis Encryption in-transit: Yes Encryption at-rest: No

[ioredis] version: 4.17.3

new Cluster([
  {"port":6379,"host":"clustercfg.test1.xxxxxx.use2.cache.amazonaws.com"}
], {
    dnsLookup: (address, callback) => {
            console.log('====[dnsLookup]====');
            return callback(null, address);
    },
    redisOptions: {
            tls: {},
    },
})

Error: ClusterAllFailedError: Failed to refresh slots cache.

What am I missing ?

keyvhinng avatar Jul 12 '20 23:07 keyvhinng

I guess you're missing tls.checkServerIdentity and a password, if AUTH is enabled.

I can't vouch for all of the following, but FYI:

return new IORedis.Cluster(endpoints, {
  // https://github.com/luin/ioredis#special-note-aws-elasticache-clusters-with-tls
  // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
  // @ts-ignore(TS2554) https://github.com/luin/ioredis/pull/1143
  dnsLookup: (address, callback) => callback(null, address),
  redisOptions: {
    connectionName,
    password,
    // https://github.com/luin/ioredis#reconnect-on-error
    reconnectOnError: function(err) {
      // Only reconnect when the error contains "READONLY"
      // `return 2` to resend failed command after reconnecting
      return err.message.includes('READONLY')
    },
    showFriendlyErrorStack: true,
    tls: {
      checkServerIdentity: (/*host, cert*/) => {
        // skip certificate hostname validation
        return undefined
      }
    }
  },
  slotsRefreshTimeout: 3000
})

joebowbeer avatar Jul 12 '20 23:07 joebowbeer

AUTH is not enabled. My current options (and it's still failing):

{
            slotsRefreshTimeout: 3000,
            dnsLookup: (address, callback) => callback(null, address),
            redisOptions: {
                    showFriendlyErrorStack: true,
                    tls: {
                          checkServerIdentity: (/*host, cert*/) => {
                            // skip certificate hostname validation
                            return undefined
                          }
                    },
            },
}

keyvhinng avatar Jul 13 '20 00:07 keyvhinng

I suggest setting DEBUG="ioredis:*" and see if anything turns up. I wonder if it's still trying to do AUTH.

joebowbeer avatar Jul 13 '20 00:07 joebowbeer

I found my mistake, I'm new into ElastiCache and I didn't realize I need to connect from an EC2 or AWS VPN. I fixed that and it worked.

keyvhinng avatar Jul 16 '20 16:07 keyvhinng

It's not working with https://github.com/bitnami/bitnami-docker-redis-cluster

fixes like checkServerIdentity returning undefined, DNS lookup, and other proposed fixes. ioRedis version: 4.28.1

hejkerooo avatar Dec 01 '21 07:12 hejkerooo

The only fix that seems to work for me is to up the slotsRefreshTimeout... :/

I wander why the default timeout value is so "dangerously" low. The response to the slots commands just seems to sometimes take 2 or 3 seconds for me. Too bad then that by the time the slots "response" comes the client has already given up...

Davidiusdadi avatar Dec 06 '21 15:12 Davidiusdadi

AUTH is not enabled. My current options (and it's still failing):

{
            slotsRefreshTimeout: 3000,
            dnsLookup: (address, callback) => callback(null, address),
            redisOptions: {
                    showFriendlyErrorStack: true,
                    tls: {
                          checkServerIdentity: (/*host, cert*/) => {
                            // skip certificate hostname validation
                            return undefined
                          }
                    },
            },
}

This will work without failing if you remove the dnsLookup option.

lueenavarro avatar Dec 12 '21 11:12 lueenavarro

set DEBUG="ioredis:*" and was able to see connection was timing out before establishing a secure connection via tls...fixed it by setting slotsRefreshTimeout: 10000.

here's our team's full ioredis config

const client =  new Redis.Cluster(
					[
						{
							port: nconf.get('REDIS:PORT') as any,
							host: nconf.get('REDIS:HOST') as string
						}
					],
					{
						enableAutoPipelining: true,
						slotsRefreshTimeout: 10000,
						dnsLookup: (address, callback) => callback(null, address),
						redisOptions: {
							tls: nconf.get('REDIS:TLS') as any
						}
					}
			  );

	client.on('connect', () => {
		logger.info('connected to redis server');
	});

	client.on('close', () => {
		logger.info('redis connection closed attempting reconnect');
		client.connect();
	});

	client.on('error', (error) => {
		logger.error(`redis connection error ${error}`);
	});

kidus60 avatar Sep 21 '22 01:09 kidus60

Faced similar issue while running redis cluster inside docker container https://github.com/bitnami/containers/tree/main/bitnami/redis-cluster

Fixed it using natMap option. Refer to solution posted on stackoverflow

NikithShetty avatar Oct 24 '22 14:10 NikithShetty

@kidus60 your solution worked for me. BTW what does enableAutoPipelining: true actually does?

sahilkul95 avatar Oct 10 '23 09:10 sahilkul95

i am facing the same issue when using clustered config, i have a none clustered Redis instance so when i am using the normal connection it is works on ec2 vm which is in the same vpc but when deployed on eks with docker i am getting some certificate file not found error.

here is my connection config

const options = {
  port: config.redis.port, // Redis port
  host: config.redis.host, // Redis host
  family: 4, // 4 (IPv4) or 6 (IPv6)
  password: config.redis.password,
  db: MAIN_REDIS_DB,
  enableAutoPipelining: true,
  enableOfflineQueue: false,
  tls :{}
}
export const client = new Redis(options);

ioredis version = ^4.28.2 redis engine = 7.0.7

devSajan avatar Dec 20 '23 12:12 devSajan

I am also facing the same issue below is my configuration setup "redis": "^4.5.1" "ioredis": "^5.2.4"

try { return new Redis.Cluster( [ { host:${redisUrl}, port: process.env.REDIS_PORT, }, ], { dnsLookup: (address, callback) => callback(null, address), redisOptions: {}, clusterRetryStrategy: (times) => { if (times > 1) { console.log("Cluster Memory DB redis connection error"); return new Error("Cluster Memory DB redis connection error"); } else return 10; }, } ); }

KaranMane027 avatar Jan 09 '24 12:01 KaranMane027