redis/node-redis · error · Error

no replicas available for read

Error message

no replicas available for read

What it means

`#getClient` routes reads marked for replicas through `#replicaClients`; with `replicaPoolSize` defaulting to 0 and no replicas ever pooled, that array is empty and the round-robin helper throws instead of silently falling back. It is a hard failure by design so callers know read-splitting was never actually configured.

Solutions

  1. Set `replicaPoolSize` to a positive number so the pool is populated.
  2. Ensure the deployment actually has replicas and Sentinel reports them.
  3. Route the read at the master when no replicas are required.

Example fix

// before
new RedisSentinel({ name: 'mymaster', rootNodes }); // replicaPoolSize defaults to 0
// after
new RedisSentinel({ name: 'mymaster', rootNodes, replicaPoolSize: 2 });
Defensive patterns

Strategy: validation

Validate before calling

function assertReplicasConfigured(opts: { replicaPoolSize?: number }) {
  if ((opts.replicaPoolSize ?? 0) <= 0) {
    throw new Error('Reads routed to replicas require replicaPoolSize > 0');
  }
}
assertReplicasConfigured(opts);

Type guard

function hasReplicaPool(opts: { replicaPoolSize?: number }): boolean {
  return (opts.replicaPoolSize ?? 0) > 0;
}

Try / catch

try {
  return await sentinel.getReplicaClient();
} catch (e) {
  if (String(e).includes('no replicas available for read')) {
    return await sentinel.getMasterClient(); // explicit fallback
  }
  throw e;
}

Prevention

When it happens

Trigger: Issuing a read routed to replicas (via the replica client path) when `replicaPoolSize` is 0 or when discovery connected zero replicas. The replica index helper runs before any command is sent.

Common situations: Leaving `replicaPoolSize` at its default of 0 while expecting reads to spread to replicas; topology where replicas exist but none were enumerated at connect time; replicas temporarily all down.

Related errors


AI-assisted analysis of redis/node-redis@90fd0652bc (2026-08-11). Data as JSON: /api/errors/11406471f1c58954. Report an issue: GitHub.

Appendix: source

Thrown at packages/client/lib/sentinel/index.ts:1122

  }

  #handlePubSubControlChannel(channel: Buffer, _message: Buffer) {
    this.#trace("pubsub control channel message on " + channel);
    this.#resetInBackground();
  }

  // if clientInfo is defined, it corresponds to a master client in the #masterClients array, otherwise loop around replicaClients
  #getClient(clientInfo?: ClientInfo): RedisClientType<RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping> {
    if (clientInfo !== undefined) {
      return this.#masterClients[clientInfo.id];
    }

    if (this.#replicaClientsIdx >= this.#replicaClients.length) {
      this.#replicaClientsIdx = 0;
    }

    if (this.#replicaClients.length == 0) {
      throw new Error("no replicas available for read");
    }

    return this.#replicaClients[this.#replicaClientsIdx++];
  }

  async #reset() {
    /* closing / don't reset */
    if (this.#isReady == false || this.#destroy == true) {
      return;
    }

    // already in #connect()
    if (this.#connectPromise !== undefined) {
      this.#anotherReset = true;
      return await this.#connectPromise;
    }

    try {

View on GitHub (pinned to 90fd0652bc)