redis/node-redis · error · Error

Cluster already open

Error message

Cluster already open

What it means

Thrown from RedisClusterSlots.connect() (cluster-slots.ts:232) when #isOpen is already true. Prevents a second concurrent connect/discovery over an already-open cluster. Surfaced to the caller of cluster.connect().

Source

Thrown at packages/client/lib/cluster/cluster-slots.ts:232

    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 bb5beb5657)

Solutions

  1. Connect once at startup and reuse the instance; memoize the connect() promise if multiple callers need it.
  2. Guard with cluster.isOpen before calling connect().
  3. After a full close()/destroy(), a new connect() is fine — ensure teardown completed first.

Example fix

// before
await cluster.connect();
await cluster.connect(); // throws 'Cluster already open'

// after
let ready;
function ensureConnected() { return ready ??= cluster.connect(); }
Defensive patterns

Strategy: validation

Validate before calling

if (cluster.isOpen) { /* skip */ } else { await cluster.connect(); }

Prevention

When it happens

Trigger: Calling cluster.connect() twice; awaiting connect() in a loop that already resolved; two callers racing to connect the same cluster instance.

Common situations: App startup code plus a health-check both connecting; memoization bug where the connect promise isn't shared; retry wrapper that re-enters connect().

Related errors


AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03). Data as JSON: /data/errors/b111125a3b32aa20.json. Report an issue: GitHub.