{"record":{"id":"b80c506e2be95a34","repo":"apache/druid","slug":"cannot-partition-on-multi-value-dimension-s-for","errorCode":null,"errorMessage":"Cannot partition on multi-value dimension [%s] for input row [%s]","messagePattern":"Cannot partition on multi-value dimension \\[(.+?)\\] for input row \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/iterator/RangePartitionIndexTaskInputRowIteratorBuilder.java","lineNumber":138,"sourceCode":"\n    return false;\n  }\n\n  /**\n   * Verifies that the given InputRow does not have multiple values for any dimension.\n   *\n   * @throws IAE if any of the dimension columns in the given InputRow have\n   *             multiple values.\n   */\n  private static void ensureNoMultiValuedDimensions(\n      InputRow inputRow,\n      List<String> partitionDimensions\n  ) throws IAE\n  {\n    for (String dimension : partitionDimensions) {\n      int dimensionValueCount = inputRow.getDimension(dimension).size();\n      if (dimensionValueCount > 1) {\n        throw new IAE(\n            \"Cannot partition on multi-value dimension [%s] for input row [%s]\",\n            dimension,\n            inputRow\n        );\n      }\n    }\n  }\n\n}\n","sourceCodeStart":120,"sourceCodeEnd":148,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/iterator/RangePartitionIndexTaskInputRowIteratorBuilder.java#L120-L148","documentation":"RangePartitionIndexTaskInputRowIteratorBuilder.ensureNoMultiValuedDimensions throws this IAE when a row used for range partitioning has more than one value in one of the configured partition dimensions. Range partitioning requires a single scalar value per partition dimension to compute the row's range bucket; multi-value dimensions cannot be ordered, so Druid rejects the row rather than partitioning arbitrarily.","triggerScenarios":"An input row contains multiple values for a dimension listed in the range partitionsSpec's partitionDimensions — e.g., nested/array-like data ingested without flattening — and the row iterator's single-value enforcement handler (ensureSingleValue handlers) processes it.","commonSituations":"Ingesting JSON/Avro data with repeated fields or arrays mapped to a partition dimension; missing an expression/flattener to pick one value; auto-detection turning a delimited string into a multi-value dimension; Kafka/Parquet sources with array columns.","solutions":["Add a flattenSpec or expression (e.g., array_to_string, or indexing to pick element 0) so the partition dimension is single-valued","Choose a different, inherently single-valued dimension for partitionDimensions","Filter or transform rows upstream so partition dimensions carry at most one value","Verify with a sample of the input source (druid inputSource sampler) which dimensions are multi-valued before configuring range partitioning"],"exampleFix":"// before: multi-valued dimension used directly for partitioning\n\"partitionDimensions\": [\"tags\"]\n// after: flatten to a single value in the parser\n\"flattenSpec\": { \"fields\": [{ \"name\": \"tags\", \"type\": \"path\", \"expr\": \"$.tags[0]\" }] },\n\"partitionDimensions\": [\"tags\"]","handlingStrategy":"validation","validationCode":"// verify partition dimensions are single-valued on a sample before configuring range partitioning\nfor (String dim : partitionDimensions) {\n  if (sampleRows.stream().anyMatch(r -> r.getDimension(dim) != null && r.getDimension(dim).size() > 1)) {\n    throw new IAE(\"dimension %s is multi-valued in input; flatten it before range partitioning\", dim);\n  }\n}","typeGuard":"boolean isSingleValued(InputRow row, String dim) {\n  List<String> vals = row.getDimension(dim);\n  return vals != null && vals.size() <= 1;\n}","tryCatchPattern":"catch (IAE e) {\n  if (e.getMessage().startsWith(\"Cannot partition on multi-value dimension\")) {\n    throw new SpecConfigException(\"flatten or replace partition dimension: \" + e.getMessage());\n  } throw e;\n}","preventionTips":["Use the input-source sampler to inspect dimension cardinality before setting partitionDimensions","Add flattenSpec/expressions to reduce array-like fields to single values","Prefer unambiguous scalar dimensions (ids, hashes) for range partitioning","Test ingestion specs on a small interval before full runs"],"tags":["ingestion","partitioning","multi-value-dimensions"],"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-14T11:17:12.474Z"}