{"record":{"id":"d5404b8af752b4be","repo":"apache/druid","slug":"conflicting-segment-granularities-found-s-segment","errorCode":null,"errorMessage":"Conflicting segment granularities found %s(segmentGranularity) and %s(granularitySpec.segmentGranularity).\nRemove `segmentGranularity` and set the `granularitySpec.segmentGranularity` to the expected granularity","messagePattern":"Conflicting segment granularities found (.+?)\\(segmentGranularity\\) and (.+?)\\(granularitySpec\\.segmentGranularity\\)\\.\nRemove `segmentGranularity` and set the `granularitySpec\\.segmentGranularity` to the expected granularity","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/common/task/CompactionTask.java","lineNumber":261,"sourceCode":"\n      if (!usingConcurrentLocks) {\n        throw DruidException.forPersona(DruidException.Persona.USER)\n                            .ofCategory(DruidException.Category.INVALID_INPUT)\n                            .build(\"Minor compaction is only used with REPLACE ingestion mode. Please set ioconfig[%s] to true.\", Tasks.USE_CONCURRENT_LOCKS);\n      }\n    }\n\n    this.dimensionsSpec = dimensionsSpec == null ? dimensions : dimensionsSpec;\n    this.transformSpec = transformSpec;\n    this.metricsSpec = metricsSpec;\n    // Prior to apache/druid#10843 users could specify segmentGranularity using `segmentGranularity`\n    // Now users should prefer to use `granularitySpec`\n    // In case users accidentally specify both, and they are conflicting, warn the user instead of proceeding\n    // by picking one or another.\n    if (granularitySpec != null\n        && segmentGranularity != null\n        && !segmentGranularity.equals(granularitySpec.getSegmentGranularity())) {\n      throw new IAE(StringUtils.format(\n          \"Conflicting segment granularities found %s(segmentGranularity) and %s(granularitySpec.segmentGranularity).\\n\"\n          + \"Remove `segmentGranularity` and set the `granularitySpec.segmentGranularity` to the expected granularity\",\n          segmentGranularity,\n          granularitySpec.getSegmentGranularity()\n      ));\n    }\n    if (granularitySpec == null && segmentGranularity != null) {\n      this.granularitySpec = new ClientCompactionTaskGranularitySpec(segmentGranularity, null, null);\n    } else {\n      this.granularitySpec = granularitySpec;\n    }\n    this.projections = projections;\n    this.baseTable = baseTable;\n    this.tuningConfig = tuningConfig != null ? getTuningConfig(tuningConfig) : null;\n    this.segmentProvider = new SegmentProvider(dataSource, this.ioConfig.getInputSpec());\n    // Note: The default compactionRunnerType used here should match the default runner used in CompactSegments#run\n    // when no runner is detected in the returned compactionTaskQuery.\n    this.compactionRunner = compactionRunner == null","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/common/task/CompactionTask.java#L243-L279","documentation":"CompactionTask constructor rejects a spec that sets both the legacy top-level segmentGranularity and the newer granularitySpec.segmentGranularity with different values. Because the two fields would contradict, Druid throws IAE instead of silently picking one.","triggerScenarios":"Building a CompactionTask/CompactionIOConfig JSON with \"segmentGranularity\":\"day\" plus a granularitySpec whose segmentGranularity is e.g. \"month\"; partial migration of old compaction configs to the granularitySpec form after the deprecation.","commonSituations":"Upgrading Druid versions where compaction specs were hand-edited; coordinator compaction configs edited via UI and API simultaneously; copy-paste between old and new spec examples.","solutions":["Remove the legacy top-level segmentGranularity field and keep only granularitySpec.segmentGranularity.","Make both values identical if both fields must temporarily remain (though removal is preferred).","Re-generate the compaction config from the current Druid UI/API so only granularitySpec is emitted."],"exampleFix":"// before\n\"segmentGranularity\": \"day\",\n\"granularitySpec\": { \"segmentGranularity\": \"month\" }\n// after\n\"granularitySpec\": { \"segmentGranularity\": \"month\" }","handlingStrategy":"validation","validationCode":"if (spec.segmentGranularity != null && spec.granularitySpec != null\n    && !spec.segmentGranularity.equals(spec.granularitySpec.getSegmentGranularity())) {\n  throw new IllegalArgumentException(\"conflicting segmentGranularity values in compaction spec\");\n}","typeGuard":null,"tryCatchPattern":"try { new CompactionTask(...); } catch (IAE e) { if (e.getMessage().contains(\"Conflicting segment granularities\")) { remove legacy field and retry; } else throw e; }","preventionTips":["Use only granularitySpec.segmentGranularity in new configs.","Search existing coordinator compaction configs for legacy segmentGranularity before upgrades.","Emit specs through the current UI/API to avoid legacy fields."],"tags":["druid","compaction","config","deprecation"],"backgroundTag":"conflicting-config-options","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"}