apache/druid · error · IllegalArgumentException

Cannot partition on multi-value dimension [%s] for input row

Error message

Cannot partition on multi-value dimension [%s] for input row [%s]

What it means

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.

Source

Thrown at indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/iterator/RangePartitionIndexTaskInputRowIteratorBuilder.java:138

    return false;
  }

  /**
   * Verifies that the given InputRow does not have multiple values for any dimension.
   *
   * @throws IAE if any of the dimension columns in the given InputRow have
   *             multiple values.
   */
  private static void ensureNoMultiValuedDimensions(
      InputRow inputRow,
      List<String> partitionDimensions
  ) throws IAE
  {
    for (String dimension : partitionDimensions) {
      int dimensionValueCount = inputRow.getDimension(dimension).size();
      if (dimensionValueCount > 1) {
        throw new IAE(
            "Cannot partition on multi-value dimension [%s] for input row [%s]",
            dimension,
            inputRow
        );
      }
    }
  }

}

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Add a flattenSpec or expression (e.g., array_to_string, or indexing to pick element 0) so the partition dimension is single-valued
  2. Choose a different, inherently single-valued dimension for partitionDimensions
  3. Filter or transform rows upstream so partition dimensions carry at most one value
  4. Verify with a sample of the input source (druid inputSource sampler) which dimensions are multi-valued before configuring range partitioning

Example fix

// before: multi-valued dimension used directly for partitioning
"partitionDimensions": ["tags"]
// after: flatten to a single value in the parser
"flattenSpec": { "fields": [{ "name": "tags", "type": "path", "expr": "$.tags[0]" }] },
"partitionDimensions": ["tags"]
Defensive patterns

Strategy: validation

Validate before calling

// verify partition dimensions are single-valued on a sample before configuring range partitioning
for (String dim : partitionDimensions) {
  if (sampleRows.stream().anyMatch(r -> r.getDimension(dim) != null && r.getDimension(dim).size() > 1)) {
    throw new IAE("dimension %s is multi-valued in input; flatten it before range partitioning", dim);
  }
}

Type guard

boolean isSingleValued(InputRow row, String dim) {
  List<String> vals = row.getDimension(dim);
  return vals != null && vals.size() <= 1;
}

Try / catch

catch (IAE e) {
  if (e.getMessage().startsWith("Cannot partition on multi-value dimension")) {
    throw new SpecConfigException("flatten or replace partition dimension: " + e.getMessage());
  } throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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/b80c506e2be95a34. Report an issue: GitHub.