{"record":{"id":"ee461fd2350c1d33","repo":"apache/druid","slug":"metric-mismatch-index-d-s-s","errorCode":null,"errorMessage":"Metric mismatch, index[%d] [%s] != [%s]","messagePattern":"Metric mismatch, index\\[(.+?)\\] \\[(.+?)\\] != \\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/IndexMergerBase.java","lineNumber":429,"sourceCode":"       */\n      if (metricIndex > -1) {\n        sortedMetricAggs[metricIndex] = metricAgg;\n      }\n    }\n\n    /*\n      If there is nothing at sortedMetricAggs[i], then we did not have a metricAgg whose name matched the name\n      of the ith element of mergedMetrics. I.e. There was a metric in the indices to merge that we did not ask for.\n     */\n    for (int i = 0; i < sortedMetricAggs.length; i++) {\n      if (sortedMetricAggs[i] == null) {\n        throw new IAE(\"Indices to merge contained metric[%s], but requested metrics did not\", mergedMetrics.get(i));\n      }\n    }\n\n    for (int i = 0; i < mergedMetrics.size(); i++) {\n      if (!sortedMetricAggs[i].getName().equals(mergedMetrics.get(i))) {\n        throw new IAE(\n            \"Metric mismatch, index[%d] [%s] != [%s]\",\n            i,\n            sortedMetricAggs[i].getName(),\n            mergedMetrics.get(i)\n        );\n      }\n    }\n\n    Function<List<TransformableRowIterator>, TimeAndDimsIterator> rowMergerFn;\n    if (rollup) {\n      rowMergerFn = rowIterators -> new RowCombiningTimeAndDimsIterator(rowIterators, sortedMetricAggs, mergedMetrics);\n    } else {\n      rowMergerFn = MergingRowIterator::new;\n    }\n\n    List<Metadata> metadataList = Lists.transform(indexes, IndexableAdapter::getMetadata);\n    AggregatorFactory[] combiningMetricAggs = new AggregatorFactory[sortedMetricAggs.length];\n    for (int i = 0; i < sortedMetricAggs.length; i++) {","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/IndexMergerBase.java#L411-L447","documentation":"Thrown during segment merging when the metrics actually present in the merged indices do not line up, position by position, with the requested (sorted) metrics for the output segment. Druid validates that each aggregator name in the requested aggregator spec matches the metric found at the same index in the merged segment; any ordering or naming divergence aborts the merge. This is an internal consistency check to prevent writing a corrupt segment with misaligned metric columns.","triggerScenarios":"Calling IndexMerger.merge (directly or via multiphaseMerge/phaseOutput) with an AggregatorFactory[] whose names/order differ from the metrics in the segments being merged, or whose rollup/metric set was altered between input segments.","commonSituations":"Changing aggregator definitions (renaming a metric or reordering aggregators) while re-ingesting or re-indexing old segments; supervisor spec updates between segments; schema drift between generation segments during compaction.","solutions":["Align the AggregatorFactory[] passed to merge with the metric names and order present in the input segments","Re-ingest or normalize the input segments so all share the same metric schema","Regenerate segments with a consistent dataSchema instead of hand-merging mismatched segments","Check intermediate merges (multiphaseMerge) so phase output metrics match the final requested metrics"],"exampleFix":"// before\naggs = new AggregatorFactory[]{new LongSumAggregatorFactory(\"sum\", \"val\"), new CountAggregatorFactory(\"cnt\")};\nmerger.merge(segments, false, ..., aggs);\n// after\n// derive aggregators in the same name/order the segments contain\naggs = new AggregatorFactory[]{new CountAggregatorFactory(\"cnt\"), new LongSumAggregatorFactory(\"sum\", \"val\")};\nmerger.merge(segments, false, ..., aggs);","handlingStrategy":"validation","validationCode":"final Set<String> segMetrics = segments.stream().flatMap(s -> Arrays.stream(s.getMetrics())) ...; // compare names & order to requestedAggs before merge\nif (!Arrays.stream(aggs).map(AggregatorFactory::getName).collect(Collectors.toList()).equals(expectedMetricNames)) { throw new IllegalArgumentException(\"aggregator names/order do not match segment metrics\"); }","typeGuard":"boolean metricsMatch(Segment[] segs, AggregatorFactory[] aggs) { ... }","tryCatchPattern":null,"preventionTips":["Derive aggregators from the input segments' schema rather than a hand-written spec","Keep dataSchema stable across incremental ingestion of the same datasource","Verify metric schema consistency before compaction"],"tags":["druid","segment-merge","schema-mismatch"],"backgroundTag":"schema-validation-failed","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"}