redis/node-redis · critical · Error
None of the sentinels are available
Error message
None of the sentinels are available
What it means
Thrown by observe() after iterating every node in #sentinelRootNodes and failing to connect (or failing the SENTINEL SENTINELS/MASTER/REPLICAS queries) on all of them (sentinel/index.ts:1363). observe() is the discovery phase of connect()/reconfigure; if no sentinel can be reached, there is no topology to act on and the error propagates up through #connect()'s retry loop (bounded by maxCommandRediscovers) to the public connect().
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 bb5beb5657)
Solutions
- Verify each sentinelRootNodes entry is reachable: `redis-cli -h <host> -p <port> PING`.
- Check sentinelClientOptions credentials/TLS match the sentinel's requirepass/TLS settings.
- Confirm DNS resolution and firewall rules for the sentinel ports (default 26379) from the client host.
- Listen for the 'error' event (emitted per failed sentinel in observe) to see the underlying socket error.
Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight: can we reach any sentinel at all?
import net from 'node:net';
async function anySentinelReachable(nodes) {
for (const { host, port } of nodes) {
if (await new Promise(res => {
const s = net.connect({ host, port: Number(port) });
s.once('connect', () => { s.destroy(); res(true); });
s.once('error', () => res(false));
setTimeout(() => { s.destroy(); res(false); }, 1000);
})) return true;
}
return false;
}
if (!(await anySentinelReachable(options.sentinelRootNodes))) {
throw new Error('no sentinel seed reachable — refusing to call connect()');
} Try / catch
async function connectWithRetry(sentinel, attempts = 5) {
for (let i = 0; i < attempts; i++) {
try {
await sentinel.connect();
return;
} catch (e) {
if (e instanceof Error && /None of the sentinels are available/.test(e.message) && i < attempts - 1) {
await new Promise(r => setTimeout(r, 1000 * (i + 1)));
continue;
}
throw e;
}
}
} Prevention
- Run a reachability check (PING) on each sentinel seed before connecting.
- Verify sentinelClientOptions auth/TLS match the sentinels' requirepass/TLS.
- Provide multiple sentinel seeds across hosts/AZs.
- Attach an 'error' listener to capture per-node socket errors during observe.
When it happens
Trigger: Calling connect() (or triggering a background reconfigure) when all seed/discovered sentinel nodes are unreachable: wrong host/port, network partition, firewall, DNS failure, or sentinel auth (requirepass) mismatch in sentinelClientOptions.
Common situations: Initial connect in an environment where the sentinel hostnames resolve but ports are blocked; TLS misconfig; sentinelClientOptions missing the password for a sentinel that enforces requirepass; all sentinels down during a cluster-wide outage.
Related errors
- Couldn't connect to any sentinel node
- couldn't connect to any sentinels
- Unknown RESP type ${type} "${String.fromCharCode(type)}"
- One (or more) of the watched keys has been changed
- Client reconnected after WATCH
AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03).
Data as JSON: /data/errors/bf050b9a23dc2f28.json.
Report an issue: GitHub.