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
- Verify root node host/port reachability: telnet/nc to each node, and confirm CLUSTER INFO returns cluster_enabled:1.
- Check AUTH/credentials and TLS settings match across all root nodes.
- Retry connect() with backoff — a transient full outage may clear.
- 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
- Validate root node addresses and ports before startup.
- Confirm each root node is cluster-enabled (CLUSTER INFO).
- Verify AUTH/TLS config matches all root nodes.
- Add startup retry with backoff for transient full outages.
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
- Cluster already open
- Cluster closed
- The client is closed
- The client is offline
- Request policy ${requestPolicy} produced no target nodes
AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03).
Data as JSON: /data/errors/5eca4ef2a745ef16.json.
Report an issue: GitHub.