redis/node-redis · critical · RootNodesUnavailableError

All the root nodes are unavailable

Error message

All the root nodes are unavailable

What it means

Thrown as RootNodesUnavailableError (cluster-slots.ts:269) after #discoverWithRootNodes exhausts every root node without one succeeding. Each root node either failed to connect or failed to return slot topology. This is the hard failure of cluster.connect() — the cluster cannot be used until at least one root node is reachable.

Source

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

  }

  async #discoverWithRootNodes() {
    const start = Math.floor(Math.random() * this.#options.rootNodes.length);
    for (let i = start; i < this.#options.rootNodes.length; i++) {
      if (!this.#isOpen) throw new Error('Cluster closed');
      if (await this.#discover(this.#options.rootNodes[i])) {
        return;
      }
    }

    for (let i = 0; i < start; i++) {
      if (!this.#isOpen) throw new Error('Cluster closed');
      if (await this.#discover(this.#options.rootNodes[i])) {
        return;
      }
    }

    throw new RootNodesUnavailableError();
  }

  #resetSlots() {
    this.slots = new Array(RedisClusterSlots.#SLOTS);
    this.masters = [];
    this.replicas = [];
    this._randomNodeIterator = undefined;
  }

  async #discover(rootNode: RedisClusterClientOptions) {
    this.clientSideCache?.clear();
    this.clientSideCache?.disable();

    try {
      const addressesInUse = new Set<string>(),
        promises: Array<Promise<unknown>> = [],
        eagerConnect = this.#options.minimizeConnections !== true;

View on GitHub (pinned to bb5beb5657)

Solutions

  1. Verify root node host/port reachability: telnet/nc to each node, and confirm CLUSTER INFO returns cluster_enabled:1.
  2. Check AUTH/credentials and TLS settings match across all root nodes.
  3. Retry connect() with backoff — a transient full outage may clear.
  4. Ensure at least one root node is a cluster-enabled Redis (not a standalone or sentinel node).

Example fix

// before
const cluster = createCluster({ rootNodes: [{ socket: { host: 'wrong-host', port: 7000 } }] });
await cluster.connect(); // RootNodesUnavailableError

// after
const cluster = createCluster({
  rootNodes: [
    { socket: { host: 'node-0.cluster', port: 7000 } },
    { socket: { host: 'node-1.cluster', port: 7000 } }
  ]
});
await cluster.connect();
Defensive patterns

Strategy: retry

Validate before calling

import net from 'node:net';
async function reachable(host: string, port: number, ms = 1000): Promise<boolean> {
  return new Promise(res => {
    const s = net.connect({ host, port });
    s.setTimeout(ms);
    s.on('connect', () => { s.destroy(); res(true); });
    s.on('error', () => res(false));
    s.on('timeout', () => { s.destroy(); res(false); });
  });
}
// before connect: assert at least one root node is reachable

Type guard

import { RootNodesUnavailableError } from '@redis/client';
function isRootNodesUnavailable(e: unknown): boolean {
  return e instanceof Error && (e instanceof RootNodesUnavailableError || /root nodes are unavailable/i.test(e.message));
}

Try / catch

for (let i = 0; i < 5; i++) {
  try { await cluster.connect(); break; }
  catch (e) { if (isRootNodesUnavailable(e) && i < 4) { await sleep(2 ** i * 500); continue; } throw e; }
}

Prevention

When it happens

Trigger: cluster.connect() where every entry in rootNodes is unreachable (wrong host/port, firewalled, DNS failure, all nodes down, auth failing on all).

Common situations: Wrong root node addresses in config; network/firewall blocking the Redis port; all cluster nodes down during a full outage; credentials rotated so AUTH fails on every node; pointing at a standalone Redis instead of a cluster (CLUSTER SLOTS fails).

Related errors


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