{"record":{"id":"d0f620fe38327fb6","repo":"apache/druid","slug":"invalid-bucketbycount-d","errorCode":null,"errorMessage":"Invalid bucketByCount [%d]","messagePattern":"Invalid bucketByCount \\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/frame/key/ClusterBy.java","lineNumber":61,"sourceCode":" * details about bucket keys.\n */\npublic class ClusterBy\n{\n  private final List<KeyColumn> columns;\n  private final int bucketByCount;\n  private final boolean sortable;\n\n  @JsonCreator\n  public ClusterBy(\n      @JsonProperty(\"columns\") List<KeyColumn> columns,\n      @JsonProperty(\"bucketByCount\") int bucketByCount\n  )\n  {\n    this.columns = Preconditions.checkNotNull(columns, \"columns\");\n    this.bucketByCount = bucketByCount;\n\n    if (bucketByCount < 0 || bucketByCount > columns.size()) {\n      throw new IAE(\"Invalid bucketByCount [%d]\", bucketByCount);\n    }\n\n    // Key must be 100% sortable or 100% nonsortable. If empty, call it sortable.\n    boolean sortable = true;\n\n    for (int i = 0; i < columns.size(); i++) {\n      final KeyColumn column = columns.get(i);\n\n      if (i == 0) {\n        sortable = column.order().sortable();\n      } else if (sortable != column.order().sortable()) {\n        throw new IAE(\"Cannot mix sortable and unsortable key columns\");\n      }\n    }\n\n    this.sortable = sortable;\n  }\n","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/frame/key/ClusterBy.java#L43-L79","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the clustering/partitioning configuration so bucketByCount matches the number of cluster key columns (or is omitted for default).","Check code that computes bucketByCount — it must derive from the same columns list passed to ClusterBy.","Validate config before job submission: 0 <= bucketByCount <= columns.size().","If using Druid MSQ, review querySpec tuning/partitioning settings that set bucketByCount."],"exampleFix":"// before\nnew ClusterBy(columns, columns.size() + 1); // IAE\n// after\nint bucketByCount = Math.min(configuredBucketColumns.size(), columns.size());\nnew ClusterBy(columns, bucketByCount);","handlingStrategy":"validation","validationCode":"if (bucketByCount < 0 || bucketByCount > columns.size()) {\n  throw new IllegalArgumentException(\"bucketByCount must be in [0, \" + columns.size() + \"]\");\n}","typeGuard":"static boolean isValidBucketByCount(List<KeyColumn> columns, int bucketByCount) {\n  return bucketByCount >= 0 && bucketByCount <= columns.size();\n}","tryCatchPattern":"try {\n  new ClusterBy(columns, bucketByCount);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Invalid bucketByCount\")) {\n    // fall back to sane default\n    new ClusterBy(columns, Math.min(bucketByCount, columns.size()));\n  } else {\n    throw e;\n  }\n}","preventionTips":["Derive bucketByCount from the same columns list passed to ClusterBy.","Validate clustering specs before job submission.","When configuring MSQ partitioning, keep bucketKeyCount consistent with CLUSTERED BY columns.","Write unit tests for spec-to-ClusterBy translation."],"tags":["configuration","validation","druid","msq"],"backgroundTag":"invalid-argument-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}