apache/druid · error · IllegalStateException

forceGuaranteedRollup is set but partitionsSpec [%s] is not

Error message

forceGuaranteedRollup is set but partitionsSpec [%s] is not a single_dim or hash partition spec.

What it means

Thrown by runHashPartitionMultiPhaseParallel when forceGuaranteedRollup is set but the tuning config's partitionsSpec is not a HashedPartitionsSpec. Multi-phase parallel ingestion (secondary partitioning phases) only supports hash (or range/single-dim) partitioning; dynamic partitioning cannot participate in the multi-phase perfect-rollup flow.

Source

Thrown at indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/ParallelIndexSupervisorTask.java:741

                      .getDataSchema()
                      .getGranularitySpec()
                      .withIntervals(new ArrayList<>(intervals))
              )
          );
    } else {
      return ingestionSchema;
    }
  }

  @VisibleForTesting
  TaskStatus runHashPartitionMultiPhaseParallel(TaskToolbox toolbox) throws Exception
  {
    TaskState state;
    ParallelIndexIngestionSpec ingestionSchemaToUse = ingestionSchema;

    if (!(ingestionSchema.getTuningConfig().getPartitionsSpec() instanceof HashedPartitionsSpec)) {
      // only range and hash partitioning is supported for multiphase parallel ingestion, see runMultiPhaseParallel()
      throw new ISE(
          "forceGuaranteedRollup is set but partitionsSpec [%s] is not a single_dim or hash partition spec.",
          ingestionSchema.getTuningConfig().getPartitionsSpec()
      );
    }

    final Map<Interval, Integer> intervalToNumShards;
    HashedPartitionsSpec partitionsSpec = (HashedPartitionsSpec) ingestionSchema.getTuningConfig().getPartitionsSpec();
    final boolean needsInputSampling =
        partitionsSpec.getNumShards() == null
        || ingestionSchemaToUse.getDataSchema().getGranularitySpec().inputIntervals().isEmpty();
    if (needsInputSampling) {
      // 0. need to determine intervals and numShards by scanning the data
      LOG.info("Needs to determine intervals or numShards, beginning %s phase.", PartialDimensionCardinalityTask.TYPE);
      ParallelIndexTaskRunner<PartialDimensionCardinalityTask, DimensionCardinalityReport> cardinalityRunner =
          createRunner(
              toolbox,
              this::createPartialDimensionCardinalityRunner
          );

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Change partitionsSpec to {"type":"hash", ...} (or single_dim/range) with appropriate numShards/maxNumPartitions.
  2. Remove forceGuaranteedRollup if perfect rollup is not actually needed, allowing dynamic partitioning.
  3. Verify via the task's spec in the overlord UI which partitionsSpec the task actually received.

Example fix

// before
"partitionsSpec": { "type": "dynamic" }, "forceGuaranteedRollup": true
// after
"partitionsSpec": { "type": "hash", "numShards": 8, "partitionDimensions": [] }, "forceGuaranteedRollup": true
Defensive patterns

Strategy: validation

Validate before calling

if (forceGuaranteedRollup && !(tuningConfig.getPartitionsSpec() instanceof HashedPartitionsSpec)) {
  throw new IllegalArgumentException("multi-phase perfect rollup needs a hash (or range) partitionsSpec");
}

Prevention

When it happens

Trigger: Running perfect-rollup multi-phase ingestion with partitionsSpec left as 'dynamic' or another non-hash type; misconfigured specs that pass the constructor check (e.g. via an older code path) but fail in runHashPartitionMultiPhaseParallel.

Common situations: Configuring forceGuaranteedRollup=true and forgetting to switch partitionsSpec from dynamic to hash; older task templates predating range-partition support; specs edited by hand between phases.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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