redis/node-redis · error · Error

Cannot find node

Error message

Cannot find node ${address}

What it means

Thrown when an ASK redirect names a node address that cannot be found in the cluster topology, even after a fresh rediscovery attempt via slots.rediscover(). The node that the ASK message points to either left the cluster or its address format doesn't match any known node. The client cannot determine where to send the command.

Solutions

  1. Retry the command — by the next attempt the topology may have stabilized and MOVED (not ASK) will resolve the new owner
  2. Verify the node address from the error is present in CLUSTER NODES output on the seed nodes
  3. Ensure all cluster nodes use consistent address formats (all IP:port, not mixed hostname and IP)
  4. Check for ongoing failover events and wait for cluster state to return to ok

Example fix

// The error is transient — wrap cluster commands in a retry helper
async function withRetry<T>(fn: () => Promise<T>, retries = 3): Promise<T> {
  try {
    return await fn();
  } catch (err) {
    if (retries > 0 && err instanceof Error && err.message.startsWith('Cannot find node')) {
      await new Promise(r => setTimeout(r, 500));
      return withRetry(fn, retries - 1);
    }
    throw err;
  }
}

// usage
await withRetry(() => cluster.get('mykey'));
Defensive patterns

Strategy: retry

Type guard

function isNodeNotFound(err: unknown): boolean {
  return err instanceof Error && err.message.startsWith('Cannot find node');
}

Try / catch

async function withNodeRetry<T>(fn: () => Promise<T>, retries = 3): Promise<T> {
  try {
    return await fn();
  } catch (err) {
    if (retries > 0 && err instanceof Error && err.message.startsWith('Cannot find node')) {
      await new Promise(r => setTimeout(r, 500));
      return withNodeRetry(fn, retries - 1);
    }
    throw err;
  }
}

Prevention

When it happens

Trigger: During failover, the old master's address appears in the ASK response but the new topology (after rediscovery) no longer lists it; the node crashed and was removed from the cluster while the command was in-flight; address format mismatch (e.g. hostname vs IP, or missing port) between the ASK payload and the slots table.

Common situations: Node crash during command execution; network partition where some nodes report a topology the client never converges on; DNS-based node addresses that resolve differently across calls; cluster reconfiguration (node removal) while traffic is flowing.

Related errors


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

Appendix: source

Thrown at packages/client/lib/cluster/index.ts:754

          }

          if (err.message.startsWith('ASK')) {
            publish(CHANNELS.ERROR, () => ({
              error: err,
              origin: 'cluster',
              internal: true,
              clientId: client._clientId,
              retryCount: i,
            }));
            const address = err.message.substring(err.message.lastIndexOf(' ') + 1);
            let redirectTo = await this._slots.getMasterByAddress(address);
            if (!redirectTo) {
              await this._slots.rediscover(client);
              redirectTo = await this._slots.getMasterByAddress(address);
            }

            if (!redirectTo) {
              throw new Error(`Cannot find node ${address}`);
            }

            client = redirectTo;
            myFn = this._handleAsk(fn);
            continue;
          }

          if (err.message.startsWith('MOVED')) {
            publish(CHANNELS.ERROR, () => ({
              error: err,
              origin: 'cluster',
              internal: true,
              clientId: client._clientId,
              retryCount: i,
            }));
            await this._slots.rediscover(client);
            client = (await this._slots.getClientAndSlotNumber(parser.firstKey, isReadonly)).client;
            continue;

View on GitHub (pinned to 90fd0652bc)