apache/druid · error · IllegalArgumentException

Invalid bucketByCount [%d]

Error message

Invalid bucketByCount [%d]

What it means

ClusterBy's constructor requires bucketByCount to be a valid index bound: non-negative and no larger than the number of clustering columns. Passing an out-of-range value means the caller's partitioning configuration is inconsistent — it claims to bucket by more columns than exist (or a negative count).

Source

Thrown at processing/src/main/java/org/apache/druid/frame/key/ClusterBy.java:61

 * details about bucket keys.
 */
public class ClusterBy
{
  private final List<KeyColumn> columns;
  private final int bucketByCount;
  private final boolean sortable;

  @JsonCreator
  public ClusterBy(
      @JsonProperty("columns") List<KeyColumn> columns,
      @JsonProperty("bucketByCount") int bucketByCount
  )
  {
    this.columns = Preconditions.checkNotNull(columns, "columns");
    this.bucketByCount = bucketByCount;

    if (bucketByCount < 0 || bucketByCount > columns.size()) {
      throw new IAE("Invalid bucketByCount [%d]", bucketByCount);
    }

    // Key must be 100% sortable or 100% nonsortable. If empty, call it sortable.
    boolean sortable = true;

    for (int i = 0; i < columns.size(); i++) {
      final KeyColumn column = columns.get(i);

      if (i == 0) {
        sortable = column.order().sortable();
      } else if (sortable != column.order().sortable()) {
        throw new IAE("Cannot mix sortable and unsortable key columns");
      }
    }

    this.sortable = sortable;
  }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Fix the clustering/partitioning configuration so bucketByCount matches the number of cluster key columns (or is omitted for default).
  2. Check code that computes bucketByCount — it must derive from the same columns list passed to ClusterBy.
  3. Validate config before job submission: 0 <= bucketByCount <= columns.size().
  4. If using Druid MSQ, review querySpec tuning/partitioning settings that set bucketByCount.

Example fix

// before
new ClusterBy(columns, columns.size() + 1); // IAE
// after
int bucketByCount = Math.min(configuredBucketColumns.size(), columns.size());
new ClusterBy(columns, bucketByCount);
Defensive patterns

Strategy: validation

Validate before calling

if (bucketByCount < 0 || bucketByCount > columns.size()) {
  throw new IllegalArgumentException("bucketByCount must be in [0, " + columns.size() + "]");
}

Type guard

static boolean isValidBucketByCount(List<KeyColumn> columns, int bucketByCount) {
  return bucketByCount >= 0 && bucketByCount <= columns.size();
}

Try / catch

try {
  new ClusterBy(columns, bucketByCount);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Invalid bucketByCount")) {
    // fall back to sane default
    new ClusterBy(columns, Math.min(bucketByCount, columns.size()));
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Constructing ClusterBy (e.g. when translating a MSQ/DurableStorage clustering spec) with bucketByCount < 0 or bucketByCount > columns.size(), typically from a misconfigured clustering spec or a bug computing the count.

Common situations: Query/ingestion config specifying more bucket-key columns than the actual cluster key columns; programmatic assembly of ClusterBy where the count was computed from a different column list; version changes altering default bucket counts.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/d0f620fe38327fb6. Report an issue: GitHub.