redis/node-redis · error · Error
Cluster already open
Error message
Cluster already open
What it means
Thrown by RedisClusterSlots.connect() when #isOpen is already true. The cluster permits exactly one connect() call per lifecycle; a second call indicates the cluster was already connected or is mid-connect.
Solutions
- Guard with if (!cluster.isOpen) await cluster.connect().
- Centralize cluster creation and connect() in a single startup module.
- Call cluster.disconnect() before re-connecting if you genuinely need a fresh topology load.
- Share the connected cluster instance rather than re-connecting per module.
Example fix
// before
await cluster.connect();
await cluster.connect(); // throws 'Cluster already open'
// after
if (!cluster.isOpen) {
await cluster.connect();
} Defensive patterns
Strategy: validation
Validate before calling
if (!cluster.isOpen) {
await cluster.connect();
} Type guard
function shouldConnectCluster(cluster: RedisClusterType): boolean {
return !cluster.isOpen;
} Try / catch
try {
await cluster.connect();
} catch (e) {
if (e instanceof Error && e.message === 'Cluster already open') return;
throw e;
} Prevention
- Guard every cluster.connect() with if (!cluster.isOpen).
- Centralize cluster creation and connection in one bootstrap module.
- Share the connected cluster singleton across consumers.
When it happens
Trigger: Calling await cluster.connect() twice without an intervening cluster.disconnect()/destroy(). Calling connect() from two modules that share the cluster instance. Calling connect() after the cluster auto-connected during the first command.
Common situations: Hot-reload double-running init code; multiple bootstrap modules each calling connect() on a shared singleton cluster; calling connect() in a retry loop after a partial success.
Related errors
- Socket already opened
- The client is closed
- All the root nodes are unavailable
- Client Side Caching is only supported with RESP3
- Cluster closed
AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11).
Data as JSON: /api/errors/b111125a3b32aa20.
Report an issue: GitHub.
Appendix: source
Thrown at packages/client/lib/cluster/cluster-slots.ts:301
this.#himportRegistry = options.himportRegistry ?? new FieldsetRegistry();
this.#clusterClientId = clusterClientId;
this.#reconnectionTracker = new ClusterReconnectionTracker(options.topologyRefreshOnReconnectionAttemptStrategy);
if (options?.clientSideCache) {
if (options.clientSideCache instanceof PooledClientSideCacheProvider) {
this.clientSideCache = options.clientSideCache;
} else {
this.clientSideCache = new BasicPooledClientSideCache(options.clientSideCache)
}
}
this.#clientFactory = RedisClient.factory(this.#options);
this.#emit = emit;
}
async connect() {
if (this.#isOpen) {
throw new Error('Cluster already open');
}
this.#isOpen = true;
this.#isReady = false;
try {
await this.#discoverWithRootNodes();
// `destroy()` may have run while discovery was in flight; if so, this
// resolution is stale and must not resurrect readiness for a session
// that's already been torn down.
if (this.#isOpen) {
this.#isReady = true;
this.#emit('connect');
}
} catch (err) {
this.#isOpen = false;
this.#isReady = false;
throw err;
}View on GitHub (pinned to 90fd0652bc)