redis/jedis · error · JedisClusterOperationException

Cluster slots have holes.

Error message

Cluster slots have holes.

What it means

Thrown when CLUSTER SLOTS returns data whose slot sequence fails checkClusterSlotSequence — the 16384 hash slots are not covered contiguously (holes or gaps), so the client cannot build a complete slot map and key routing would be unreliable. Usually indicates a partially resharded or degraded cluster.

Solutions

  1. Complete pending resharding operations so all 16384 slots are assigned (redis-cli cluster fix)
  2. Check cluster_state and slot coverage with CLUSTER INFO / redis-cli cluster nodes
  3. Retry discovery after the cluster finishes resharding or failover
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at src/main/java/redis/clients/jedis/JedisClusterInfoCache.java:154 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at src/main/java/redis/clients/jedis/JedisClusterInfoCache.java:154

    if (slots.size() != Protocol.CLUSTER_HASHSLOTS) {
      return false;
    }
    for (int i = 0; i < Protocol.CLUSTER_HASHSLOTS; ++i) {
      if (i != slots.get(i)) {
        return false;
      }
    }
    return true;
  }

  public void discoverClusterNodesAndSlots(Connection jedis) {
    List<Object> slotsInfo = executeClusterSlots(jedis);
    if (System.getProperty(INIT_NO_ERROR_PROPERTY) == null) {
      if (slotsInfo.isEmpty()) {
        throw new JedisClusterOperationException("Cluster slots list is empty.");
      }
      if (!checkClusterSlotSequence(slotsInfo)) {
        throw new JedisClusterOperationException("Cluster slots have holes.");
      }
    }
    w.lock();
    try {
      reset();
      for (Object slotInfoObj : slotsInfo) {
        List<Object> slotInfo = (List<Object>) slotInfoObj;

        if (slotInfo.size() <= MASTER_NODE_INDEX) {
          continue;
        }

        List<Integer> slotNums = getAssignedSlotArray(slotInfo);

        // hostInfos
        int size = slotInfo.size();
        for (int i = MASTER_NODE_INDEX; i < size; i++) {
          List<Object> hostInfos = (List<Object>) slotInfo.get(i);

View on GitHub (pinned to 6dac31d4c2)