{"record":{"id":"2396223783c06291","repo":"apache/druid","slug":"forceguaranteedrollup-is-set-but-partitionsspec","errorCode":null,"errorMessage":"forceGuaranteedRollup is set but partitionsSpec [%s] is not a single_dim or hash partition spec.","messagePattern":"forceGuaranteedRollup is set but partitionsSpec \\[(.+?)\\] is not a single_dim or hash partition spec\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/ParallelIndexSupervisorTask.java","lineNumber":741,"sourceCode":"                      .getDataSchema()\n                      .getGranularitySpec()\n                      .withIntervals(new ArrayList<>(intervals))\n              )\n          );\n    } else {\n      return ingestionSchema;\n    }\n  }\n\n  @VisibleForTesting\n  TaskStatus runHashPartitionMultiPhaseParallel(TaskToolbox toolbox) throws Exception\n  {\n    TaskState state;\n    ParallelIndexIngestionSpec ingestionSchemaToUse = ingestionSchema;\n\n    if (!(ingestionSchema.getTuningConfig().getPartitionsSpec() instanceof HashedPartitionsSpec)) {\n      // only range and hash partitioning is supported for multiphase parallel ingestion, see runMultiPhaseParallel()\n      throw new ISE(\n          \"forceGuaranteedRollup is set but partitionsSpec [%s] is not a single_dim or hash partition spec.\",\n          ingestionSchema.getTuningConfig().getPartitionsSpec()\n      );\n    }\n\n    final Map<Interval, Integer> intervalToNumShards;\n    HashedPartitionsSpec partitionsSpec = (HashedPartitionsSpec) ingestionSchema.getTuningConfig().getPartitionsSpec();\n    final boolean needsInputSampling =\n        partitionsSpec.getNumShards() == null\n        || ingestionSchemaToUse.getDataSchema().getGranularitySpec().inputIntervals().isEmpty();\n    if (needsInputSampling) {\n      // 0. need to determine intervals and numShards by scanning the data\n      LOG.info(\"Needs to determine intervals or numShards, beginning %s phase.\", PartialDimensionCardinalityTask.TYPE);\n      ParallelIndexTaskRunner<PartialDimensionCardinalityTask, DimensionCardinalityReport> cardinalityRunner =\n          createRunner(\n              toolbox,\n              this::createPartialDimensionCardinalityRunner\n          );","sourceCodeStart":723,"sourceCodeEnd":759,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/ParallelIndexSupervisorTask.java#L723-L759","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Change partitionsSpec to {\"type\":\"hash\", ...} (or single_dim/range) with appropriate numShards/maxNumPartitions.","Remove forceGuaranteedRollup if perfect rollup is not actually needed, allowing dynamic partitioning.","Verify via the task's spec in the overlord UI which partitionsSpec the task actually received."],"exampleFix":"// before\n\"partitionsSpec\": { \"type\": \"dynamic\" }, \"forceGuaranteedRollup\": true\n// after\n\"partitionsSpec\": { \"type\": \"hash\", \"numShards\": 8, \"partitionDimensions\": [] }, \"forceGuaranteedRollup\": true","handlingStrategy":"validation","validationCode":"if (forceGuaranteedRollup && !(tuningConfig.getPartitionsSpec() instanceof HashedPartitionsSpec)) {\n  throw new IllegalArgumentException(\"multi-phase perfect rollup needs a hash (or range) partitionsSpec\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use hash partitionsSpec whenever forceGuaranteedRollup is enabled","Keep task templates for perfect rollup separate from append-mode templates","Inspect the effective spec in the overlord UI before running"],"tags":["partitioning","perfect-rollup","multi-phase-ingestion"],"backgroundTag":"incompatible-source-type","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"}