redis/node-redis · error · Error

no available replicas

Error message

no available replicas

What it means

Defensive guard in RedisSentinelFactory.getReplicaClient() that throws if getReplicaNodes() somehow returned an empty array (sentinel/index.ts:1826). In normal flow getReplicaNodes() already throws error 88 or 89 before returning empty, so this is a belt-and-suspenders check against future logic changes that return [] without throwing.

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 bb5beb5657)

Solutions

  1. Treat as an assertion failure — report it with the node-redis version and steps to reproduce.
  2. In the meantime, ensure replicas are provisioned so getReplicaNodes() returns a non-empty list.
  3. Fall back to getMasterClient() for reads if replica reads are optional.
Defensive patterns

Strategy: try-catch

Validate before calling

// Defensive: call getReplicaNodes() yourself first and only build a client when non-empty.
const replicas = await factory.getReplicaNodes(); // throws 88/89 with clear cause
if (replicas.length === 0) throw new Error('no replicas available');
const client = await factory.getReplicaClient();

Try / catch

try {
  const replicaClient = await factory.getReplicaClient();
} catch (e) {
  if (e instanceof Error && /no available replicas/.test(e.message)) {
    // assertion-style fallback: use the master client for reads
    return factory.getMasterClient();
  }
  throw e;
}

Prevention

When it happens

Trigger: Effectively unreachable today; would only fire if getReplicaNodes() were changed to return an empty array instead of throwing, or if the array were mutated to empty between the call and the length check.

Common situations: Not expected in normal usage; treat as a sanity assertion. If seen, suspect a regression in getReplicaNodes or concurrent mutation.

Related errors


AI-assisted analysis of redis/node-redis@bb5beb5657 (2026-08-03). Data as JSON: /data/errors/23cec5d3c4b74a67.json. Report an issue: GitHub.