redis/node-redis · error · Error

Unknown request policy ${requestPolicy}

Error message

Unknown request policy ${requestPolicy}

What it means

Thrown from RedisCluster._executeWithPolicies (cluster/index.ts:570) when the resolved request policy string has no entry in REQUEST_ROUTERS. REQUEST_ROUTERS covers all_nodes, all_shards, multi_shard, special, default-keyless, default-keyed; an unknown policy means the command-metadata resolver returned a request_policy tip the cluster does not know how to route.

Source

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

    const responsePolicy = policy.response;

    // Fast path: default-keyed request + response — the overwhelming majority
    // of traffic (every single-key command). Route by firstKey and pass the
    // sole reply through, skipping the plan/reducer/post-reply machinery,
    // which is a no-op for this shape (the hooks only concern
    // FT.AGGREGATE/FT.CURSOR/SCAN and the remap only numeric aggregates —
    // none of them default-keyed).
    if (
      requestPolicy === REQUEST_POLICIES_WITH_DEFAULTS.DEFAULT_KEYED &&
      responsePolicy === RESPONSE_POLICIES_WITH_DEFAULTS.DEFAULT_KEYED
    ) {
      return this._execute(parser, readonly, options, makeFn(parser));
    }

    // https://redis.io/docs/latest/develop/reference/command-tips
    const router = REQUEST_ROUTERS[requestPolicy];
    if (!router) {
      throw new Error(`Unknown request policy ${requestPolicy}`);
    }
    // Validated before any per-node promise is dispatched — throwing after
    // would orphan in-flight rejections (unhandled-rejection noise) and run
    // side effects for a reply that can never be reduced.
    const reducer = RESPONSE_REDUCERS[responsePolicy];
    if (!reducer) {
      throw new Error(`Unknown response policy ${responsePolicy}`);
    }
    // Routers are typed against the erased base cluster types (routing is
    // below the typed command surface); bridge this instantiation's slots in.
    const plan = await router(
      this._slots as unknown as Parameters<typeof router>[0],
      parser,
      readonly,
      policy.keySpecs
    );

    if (plan.length === 0) {

View on GitHub (pinned to bb5beb5657)

Solutions

  1. Update the client to a version that supports the policy tip returned by the server.
  2. For custom commands, ensure they resolve to a known policy (or no policy, which falls back to default-keyed/default-keyless).
  3. Report the unknown policy string (it is interpolated in the message) to maintainers with the command and Redis version.

Example fix

// no direct user API; mitigation is version alignment / custom-command policy fix:
// before: custom module command resolves to request policy 'multi_node' (unsupported)
// after: register the command without a policy so it falls back to default-keyed
await cluster.sendCommand(['MYCMD', 'key']);
Defensive patterns

Strategy: fallback

Type guard

function isUnknownRequestPolicy(e: unknown): boolean {
  return e instanceof Error && /Unknown request policy/i.test(e.message);
}

Try / catch

try { await cluster.sendCommand(cmd); }
catch (e) {
  if (isUnknownRequestPolicy(e)) {
    // fall back to routing to a single shard master directly
    const node = await cluster.getSlotMaster(key);
    return node.sendCommand(cmd);
  }
  throw e;
}

Prevention

When it happens

Trigger: A custom command, module, or dynamically-resolved COMMAND tip yields a request policy string not in the router table (e.g. a new server tip the client version predates, or a malformed custom registration).

Common situations: Newer Redis server emitting a request_policy tip not yet supported by this client version; a hand-built custom command returning an arbitrary policy string; module commands with non-standard tips.

Related errors


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