redis/jedis · error · UnsupportedOperationException

Command '' with request policy cannot be executed in…

Error message

Command '' with  request policy cannot be executed in pipeline mode because it cannot be routed to a single slot. This command has no keys to determine routing. Use non-pipeline cluster client for this command.

What it means

Cluster pipelines (MultiNodePipelineBase) can only execute commands whose keys map to a single hash slot, because each command is sent to one node. validatePipelineCommand rejects commands with a request policy whose keys are absent or spread across multiple slots by throwing UnsupportedOperationException.

Solutions

  1. Execute the command directly on RedisClusterClient (non-pipeline) instead of the pipeline.
  2. For multi-key commands, hash-tag the keys (e.g. {user1}:a, {user1}:b) so they map to one slot.
  3. Remove keyless commands from the pipeline and batch them separately.
  4. For FLUSH-style broad commands, iterate nodes or use dedicated per-node APIs.

Example fix

// before
try (Pipeline p = clusterClient.pipelined()) {
  p.set("a", "1");
  p.mset("b", "2", "c", "3"); // keys map to multiple slots -> throws
}

// after
try (Pipeline p = clusterClient.pipelined()) {
  p.set("{h1}a", "1");
  p.mset("{h1}b", "2", "{h1}c", "3"); // same hash tag, single slot
}
Defensive patterns

Strategy: fallback

Validate before calling

// pre-flight: verify all keys of the command share one slot
String tag = key.contains("{") ? key.substring(key.indexOf('{') + 1, key.indexOf('}')) : key;
int slot = JedisClusterHashSlotUtil.getHashSlot(SafeEncoder.encode("{" + tag + "}"));
// only append to pipeline if every key hashes to the same slot

Try / catch

try {
  pipeline.appendCommand(commandObject);
} catch (UnsupportedOperationException e) {
  // execute outside the pipeline instead
  clusterClient.sendCommand(commandObject);
}

Prevention

When it happens

Trigger: Appending to a cluster pipeline a command with no keys (e.g. PING, INFO, RANDOMKEY) or with keys hashing to multiple slots (e.g. MSET with keys on different slots) — including unkeyed custom/module commands.

Common situations: Migrating a standalone Jedis pipeline to a cluster pipeline; using commands without keys in pipelined mode; empty CommandObject argument lists.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08). Data as JSON: /api/errors/787ce6da5c839412. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/redis/clients/jedis/MultiNodePipelineBase.java:236

    CommandFlagsRegistry.RequestPolicy policy =
        commandFlagsRegistry.getRequestPolicy(args);

    // For multi-node policies, check if the command can be routed to a single slot
    switch (policy) {
      case ALL_SHARDS:
      case MULTI_SHARD:
      case ALL_NODES:
      case SPECIAL:
        // If the command has keys that route to a single slot, allow it
        Set<Integer> slots = args.getKeyHashSlots();
        if (slots.size() == 1) {
          // Command can be routed to a single slot - allow it
          return;
        }

        // Command cannot be routed to a single slot - reject it
        String policyName = policy.name();
        throw new UnsupportedOperationException(
            "Command '" + args.getCommand() + "' with " + policyName + " request policy "
                + "cannot be executed in pipeline mode because it cannot be routed to a single slot. "
                + (slots.isEmpty()
                    ? "This command has no keys to determine routing. "
                    : "This command's keys map to multiple slots (" + slots.size() + " slots). ")
                + "Use non-pipeline cluster client for this command.");

      case DEFAULT:
      default:
        // DEFAULT policy and unknown policies - allow standard command execution
        // Routes to single node based on key hash
        break;
    }
  }

  @Deprecated
  public Response<Long> waitReplicas(int replicas, long timeout) {
    return appendCommand(commandObjects.waitReplicas(replicas, timeout));

View on GitHub (pinned to 6dac31d4c2)