redis/node-redis · error · Error

no available replicas

Error message

no available replicas

What it means

`getReplicaClient()` calls `getReplicaNodes()` and then defensively re-checks `replicas.length == 0`, throwing 'no available replicas'. Normally [90]/[91] already throw inside getReplicaNodes; this guard catches the edge where an empty list is returned without an earlier throw, so a replica client is never built against nothing.

Solutions

  1. Ensure the topology has healthy replicas before requesting a replica client.
  2. Set `replicaPoolSize` > 0 and confirm replicas are enumerated.
  3. Fall back to a master client when replicas are unavailable.
Defensive patterns

Strategy: fallback

Validate before calling

async function replicasExist(sentinel: { getReplicaNodes(): Promise<unknown[]> }): Promise<boolean> {
  try { return (await sentinel.getReplicaNodes()).length > 0; }
  catch { return false; }
}

Try / catch

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

Prevention

When it happens

Trigger: Reaching `getReplicaClient()` after `getReplicaNodes()` returned an empty array (the rare path that bypasses the inner throws).

Common situations: Race where topology changed between enumeration and client creation; future code paths that short-circuit getReplicaNodes; defensive duplicate of the no-replicas condition.

Related errors


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

Appendix: source

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

        }

        return replicas;
      } finally {
        client.destroy();
      }
    }

    if (connected) {
      throw new Error("No Replicas Nodes Enumerated");
    }

    throw new Error("couldn't connect to any sentinels");
  }

  async getReplicaClient() {
    const replicas = await this.getReplicaNodes();
    if (replicas.length == 0) {
      throw new Error("no available replicas");
    }

    this.#replicaIdx++;
    if (this.#replicaIdx >= replicas.length) {
      this.#replicaIdx = 0;
    }

    const replica = replicas[this.#replicaIdx];
    const socket = getMappedNode(replica.host, replica.port, this.options.nodeAddressMap);
    return RedisClient.create({
      ...this.options.nodeClientOptions,
      socket: {
        ...this.options.nodeClientOptions?.socket,
        host: socket.host,
        port: socket.port
      }
    });
  }

View on GitHub (pinned to 90fd0652bc)