{"record":{"id":"2ba71c12d8d602ab","repo":"apache/druid","slug":"s","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"exception","errorClass":"UOE","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/common/task/IndexTask.java","lineNumber":623,"sourceCode":"    // Must determine intervals if unknown, since we acquire all locks before processing any data.\n    final boolean determineIntervals = granularitySpec.inputIntervals().isEmpty();\n\n    // Must determine partitions if rollup is guaranteed and the user didn't provide a specific value.\n    final boolean determineNumPartitions = partitionsSpec.needsDeterminePartitions();\n\n    // if we were given number of shards per interval and the intervals, we don't need to scan the data\n    if (!determineNumPartitions && !determineIntervals) {\n      log.info(\"Skipping determine partition scan\");\n      if (partitionsSpec.getType() == SecondaryPartitionType.HASH) {\n        return PartialHashSegmentGenerateTask.createHashPartitionAnalysisFromPartitionsSpec(\n            granularitySpec,\n            (HashedPartitionsSpec) partitionsSpec,\n            null // not overriding numShards\n        );\n      } else if (partitionsSpec.getType() == SecondaryPartitionType.LINEAR) {\n        return createLinearPartitionAnalysis(granularitySpec, (DynamicPartitionsSpec) partitionsSpec);\n      } else {\n        throw new UOE(\"%s\", partitionsSpec.getClass().getName());\n      }\n    } else {\n      // determine intervals containing data and prime HLL collectors\n      log.info(\"Determining intervals and shardSpecs\");\n      return createShardSpecsFromInput(\n          jsonMapper,\n          ingestionSchema,\n          inputSource,\n          tmpDir,\n          granularitySpec,\n          partitionsSpec,\n          determineIntervals\n      );\n    }\n  }\n\n  private static boolean addDeterminePartitionStatsToReport(boolean isFullReport, IngestionState ingestionState)\n  {","sourceCodeStart":605,"sourceCodeEnd":641,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/common/task/IndexTask.java#L605-L641","documentation":"In IndexTask.determineShardSpecs, after handling HASH and LINEAR partitionsSpec types there is a final else branch that throws UOE for any other partitionsSpec implementation, formatting the class name into the message. It is the internal counterpart of the isReady() check, catching specs whose type changed or bypassed early validation.","triggerScenarios":"A partitionsSpec whose getType() is neither HASH nor LINEAR reaching shard-spec determination — e.g., a custom partitionsSpec implementation, a spec constructed programmatically with a non-standard type, or a type added in a newer Druid version used against an older core.","commonSituations":"Range/single-dim partitioning specs submitted to IndexTask; plugin-provided partitionsSpec types not supported by the batch engine; spec deserialized from a config written for a different engine (compaction or MSQ).","solutions":["Use partitionsSpec type \"linear\" or \"hash\" for batch index tasks","If programmatic, ensure only HashedPartitionsSpec or DynamicPartitionsSpec are constructed for IndexTask","Route range-partitioned ingestion to the compaction task or MSQ engine","Validate the spec type with a pre-submit check on tuningConfig.partitionsSpec.type"],"exampleFix":"// before\nfinal PartitionsSpec spec = new MaxSizePartitionsSpec(...); // unsupported type\n// after\nfinal PartitionsSpec spec = new HashedPartitionsSpec(null, 4, null, null, null);","handlingStrategy":"validation","validationCode":"if (partitionsSpec.getType() != SecondaryPartitionType.HASH\n    && partitionsSpec.getType() != SecondaryPartitionType.LINEAR) {\n  throw new IllegalArgumentException(\"Unsupported for IndexTask: \" + partitionsSpec.getType());\n}","typeGuard":"boolean supported(PartitionsSpec p) {\n  return p instanceof HashedPartitionsSpec || p instanceof DynamicPartitionsSpec;\n}","tryCatchPattern":"try {\n  task.determineShardSpecs(...);\n} catch (UnsupportedOperationException e) {\n  throw new IllegalStateException(\"Convert partitionsSpec to hash/linear before batch ingestion\", e);\n}","preventionTips":["Restrict spec generators to HashedPartitionsSpec/DynamicPartitionsSpec for IndexTask","Test programmatic spec construction against isReady() before run","Keep spec tooling and Druid versions aligned","Validate type field strings (\"linear\"/\"hash\") in CI"],"tags":["druid","ingestion","partitionspec","unsupported"],"backgroundTag":"unsupported-enum-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"}