{"record":{"id":"2910a46fec151e73","repo":"apache/druid","slug":"dimension-names-differ-expected-s-found-s","errorCode":null,"errorMessage":"Dimension names differ. Expected [%s] found [%s]","messagePattern":"Dimension names differ\\. Expected \\[(.+?)\\] found \\[(.+?)\\]","errorType":"validation","errorClass":"SegmentValidationException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/IndexIO.java","lineNumber":163,"sourceCode":"        );\n      }\n    }\n  }\n\n  public void validateTwoSegments(final IndexableAdapter adapter1, final IndexableAdapter adapter2)\n  {\n    if (adapter1.getNumRows() != adapter2.getNumRows()) {\n      throw new SegmentValidationException(\n          \"Row count mismatch. Expected [%d] found [%d]\",\n          adapter1.getNumRows(),\n          adapter2.getNumRows()\n      );\n    }\n    {\n      final Set<String> dimNames1 = Sets.newHashSet(adapter1.getDimensionNames(true));\n      final Set<String> dimNames2 = Sets.newHashSet(adapter2.getDimensionNames(true));\n      if (!dimNames1.equals(dimNames2)) {\n        throw new SegmentValidationException(\n            \"Dimension names differ. Expected [%s] found [%s]\",\n            dimNames1,\n            dimNames2\n        );\n      }\n      final Set<String> metNames1 = Sets.newHashSet(adapter1.getMetricNames());\n      final Set<String> metNames2 = Sets.newHashSet(adapter2.getMetricNames());\n      if (!metNames1.equals(metNames2)) {\n        throw new SegmentValidationException(\"Metric names differ. Expected [%s] found [%s]\", metNames1, metNames2);\n      }\n    }\n    try (\n        final RowIterator it1 = adapter1.getRows();\n        final RowIterator it2 = adapter2.getRows()\n    ) {\n      long row = 0L;\n      while (it1.moveToNext()) {\n        if (!it2.moveToNext()) {","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/IndexIO.java#L145-L181","documentation":"During two-segment validation, IndexIO compares the sets of dimension names of both adapters. This SegmentValidationException is thrown when the dimension name sets differ, meaning one segment has dimensions the other lacks (or vice versa).","triggerScenarios":"validateTwoSegments with segments whose getDimensionNames(true) sets are unequal — e.g. one segment has an extra or missing dimension column.","commonSituations":"Schema drift between ingestion batches; auto-discovery of dimensions adding a field in only one segment; comparing a segment before/after a transform or dimension-exclusion change; upgrading with changed schema handling.","solutions":["Diff the two dimension sets printed in the message to find the added/missing dimensions.","Align ingestion specs (dimensionsList vs auto-discovery) so both segments carry the same schema.","If the extra dimension is unintended, remove it from the input or spec and rebuild the segment.","If dimensions were intentionally renamed, the segments are legitimately different — validate against the correct reference segment instead."],"exampleFix":"// before: mismatched specs\nspec1: {\"dimensionsSpec\":{\"dimensions\":[\"page\",\"user\"]}}\nspec2: {\"dimensionsSpec\":{\"dimensions\":[\"page\"]}}\n// after: identical schemas\nspec1: {\"dimensionsSpec\":{\"dimensions\":[\"page\",\"user\"]}}\nspec2: {\"dimensionsSpec\":{\"dimensions\":[\"page\",\"user\"]}}","handlingStrategy":"validation","validationCode":"Set<String> dims1 = Sets.newHashSet(adapter1.getDimensionNames(true));\nSet<String> dims2 = Sets.newHashSet(adapter2.getDimensionNames(true));\nif (!dims1.equals(dims2)) {\n  System.out.println(\"Dim diff: only-1=\" + Sets.difference(dims1, dims2)\n      + \" only-2=\" + Sets.difference(dims2, dims1));\n}","typeGuard":null,"tryCatchPattern":"try {\n  io.validateTwoSegments(adapter1, adapter2);\n} catch (SegmentValidationException e) {\n  if (e.getMessage().startsWith(\"Dimension names differ\")) {\n    log.error(\"Schema drift detected between segments: %s\", e.getMessage());\n  }\n  throw e;\n}","preventionTips":["Use explicit dimension lists in ingestion specs instead of schema auto-discovery when exact schema parity matters.","Verify specs are identical before building segments meant to be validated against each other.","Track schema drift in streaming ingestion (Kafka/Kinesis) with schema registry checks.","Document intentional dimension renames so validators compare the correct reference segment."],"tags":["segment-validation","segments","schema"],"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-17T15:17:12.973Z"}