redis/jedis · error · UnsupportedOperationException

Not supported in cluster mode.

Error message

Not supported in cluster mode.

What it means

WAIT replicas is not exposed through the cluster command objects because in Redis Cluster wait semantics are per-connection/per-replica and the unified cluster executor does not support it here. Calling waitReplicas on a cluster client throws UnsupportedOperationException with the generic CLUSTER_UNSUPPORTED_MESSAGE.

Solutions

  1. Issue WAIT on a dedicated direct connection to the specific master node holding the key's slot
  2. Obtain a Jedis/connection from the cluster's connection provider for the key's slot and call waitReplicas there
  3. Remove/replace the WAIT call if per-node durability semantics are not required

Example fix

// before
cluster.waitReplicas(1, 1000);
// after
try (Jedis node = cluster.getConnectionForKey(slot)) {
  node.waitReplicas(1, 1000);
}
Defensive patterns

Strategy: fallback

Validate before calling

if (client instanceof UnifiedJedis && ((UnifiedJedis) client).isClusterMode()) { /* route WAIT to a direct node connection */ }

Type guard

static boolean supportsWait(JedisCommandsLike c) { return !(c instanceof ClusterCommandObjects) && !(c instanceof RedisClusterClient); }

Try / catch

try { cluster.waitReplicas(1, timeout); } catch (UnsupportedOperationException e) { nodeConn.waitReplicas(1, timeout); }

Prevention

When it happens

Trigger: Calling `clusterClient.waitReplicas(replicas, timeout)` or including WAIT in a cluster pipeline via ClusterCommandObjects.

Common situations: Replication-acknowledgement logic (write durability checks) ported from standalone Jedis to RedisClusterClient.

Related errors


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

Appendix: source

Thrown at src/main/java/redis/clients/jedis/ClusterCommandObjects.java:80

    byte[] match = params.binaryMatch();
    if (match == null || !JedisClusterHashTag.isClusterCompliantMatchPattern(match)) {
      throw new IllegalArgumentException(SCAN_PATTERN_MESSAGE);
    }
    return new CommandObject<>(commandArguments(SCAN).add(cursor).addParams(params).addHashSlotKey(match), BuilderFactory.SCAN_BINARY_RESPONSE);
  }

  @Override
  public final CommandObject<ScanResult<byte[]>> scan(byte[] cursor, ScanParams params, byte[] type) {
    byte[] match = params.binaryMatch();
    if (match == null || !JedisClusterHashTag.isClusterCompliantMatchPattern(match)) {
      throw new IllegalArgumentException(SCAN_PATTERN_MESSAGE);
    }
    return new CommandObject<>(commandArguments(SCAN).add(cursor).addParams(params).addHashSlotKey(match).add(TYPE).add(type), BuilderFactory.SCAN_BINARY_RESPONSE);
  }

  @Override
  public final CommandObject<Long> waitReplicas(int replicas, long timeout) {
    throw new UnsupportedOperationException(CLUSTER_UNSUPPORTED_MESSAGE);
  }

  @Override
  public CommandObject<KeyValue<Long, Long>> waitAOF(long numLocal, long numReplicas, long timeout) {
    throw new UnsupportedOperationException(CLUSTER_UNSUPPORTED_MESSAGE);
  }

  @Override
  public CommandObject<String> hotkeysStart(HotkeysParams params) {
    throw new UnsupportedOperationException(CLUSTER_UNSUPPORTED_MESSAGE);
  }

  @Override
  public CommandObject<String> hotkeysStop() {
    throw new UnsupportedOperationException(CLUSTER_UNSUPPORTED_MESSAGE);
  }

  @Override

View on GitHub (pinned to 6dac31d4c2)