redis/node-redis · critical · Error
None of the sentinels are available
Error message
None of the sentinels are available
What it means
`observe()` walks every sentinel root node trying to query the current master; if none of them can be reached (or all error out and get destroyed in the finally block), the loop exits and throws this terminal error. It is the Sentinel topology-discovery / failover-observation dead end.
Solutions
- Verify each `rootNodes` host:port is reachable (telnet/redis-cli ping).
- Check `sentinelClientOptions` auth (password) and TLS match the sentinels.
- Provide multiple sentinel seeds so one being down does not exhaust the list.
- Confirm network/DNS from the application host to the sentinel subnet.
Example fix
// before
rootNodes: [{ host: 'sentinel-primary', port: 26379 }]
// after
rootNodes: [
{ host: 'sentinel-1', port: 26379 },
{ host: 'sentinel-2', port: 26379 },
{ host: 'sentinel-3', port: 26379 }
] Defensive patterns
Strategy: retry
Validate before calling
async function atLeastOneSentinelReachable(rootNodes: { host: string; port: number }[], opts?: { password?: string }): Promise<boolean> {
for (const n of rootNodes) {
const c = new RedisClient({ socket: { host: n.host, port: n.port }, password: opts?.password });
try { await c.connect(); c.destroy(); return true; } catch { /* try next */ }
}
return false;
} Try / catch
async function connectWithBackoff(sentinel: { connect(): Promise<void> }, attempts = 5) {
for (let i = 0; i < attempts; i++) {
try { await sentinel.connect(); return; }
catch (e) {
if (String(e).includes('None of the sentinels are available') && i < attempts - 1) {
await new Promise(r => setTimeout(r, 500 * 2 ** i));
continue;
}
throw e;
}
}
} Prevention
- Provide multiple sentinel seeds so one outage does not exhaust discovery.
- Pre-flight ping a sentinel before app boot.
- Monitor sentinel reachability and surface it to ops.
When it happens
Trigger: All `rootNodes` sentinel endpoints unreachable during observe(); every sentinel client fails to connect or errors before returning master data. Surfaces from the internal connect/reset/scan loop, not a direct user call.
Common situations: Misconfigured or stale `rootNodes` (wrong host/port); network partition to the sentinel subnet; wrong `password`/TLS in `sentinelClientOptions`; all sentinel processes down; DNS resolution failure.
Related errors
- Couldn't connect to any sentinel node
- couldn't connect to any sentinels
- All the root nodes are unavailable
- Master Node Not Enumerated
- No Replicas Nodes Enumerated
AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11).
Data as JSON: /api/errors/bf050b9a23dc2f28.
Report an issue: GitHub.
Appendix: source
Thrown at packages/client/lib/sentinel/index.ts:1364
currentSentinel: this.getSentinelNode(),
replicaPoolSize: this.#replicaPoolSize,
useReplicas: this.useReplicas
}
return ret;
} catch (err) {
this.#trace(`observe: error ${err}`);
this.emit('error', err);
} finally {
if (client !== undefined && client.isOpen) {
this.#trace(`observe: destroying sentinel client`);
client.destroy();
}
}
}
this.#trace(`observe: none of the sentinels are available`);
throw new Error('None of the sentinels are available');
}
analyze(observed: Awaited<ReturnType<RedisSentinelInternal<M, F, S, RESP, TYPE_MAPPING>["observe"]>>) {
let master = parseNode(observed.masterData);
if (master === undefined) {
this.#trace(`analyze: no valid master node because ${observed.masterData.flags}`);
throw new Error("no valid master node");
}
if (master.host === observed.currentMaster?.host && master.port === observed.currentMaster?.port) {
this.#trace(`analyze: master node hasn't changed from ${observed.currentMaster?.host}:${observed.currentMaster?.port}`);
master = undefined;
} else {
this.#trace(`analyze: master node has changed to ${master.host}:${master.port} from ${observed.currentMaster?.host}:${observed.currentMaster?.port}`);
}
let sentinel: RedisNode | undefined = observed.sentinelConnected;
if (sentinel.host === observed.currentSentinel?.host && sentinel.port === observed.currentSentinel.port) {View on GitHub (pinned to 90fd0652bc)