apache/druid · error · SegmentValidationException

Dim [%s] types not equal. Expected %d found %d

Error message

Dim [%s] types not equal. Expected %d found %d

What it means

validateRowValues compares column capabilities of each dimension pair across the two segments. The message text mistakenly formats ColumnType objects with %d, but the failure means the two segments declare different column types (e.g. STRING vs LONG) for the same dimension. Such segments are not equivalent and validation aborts.

Source

Thrown at processing/src/main/java/org/apache/druid/segment/IndexIO.java:272

    }
    final List<Object> dims1 = rp1.getDimensionValuesForDebug();
    final List<Object> dims2 = rp2.getDimensionValuesForDebug();
    if (dims1.size() != dims2.size()) {
      throw new SegmentValidationException("Dim lengths not equal %s vs %s", dims1, dims2);
    }
    final List<String> dim1Names = adapter1.getDimensionNames(false);
    final List<String> dim2Names = adapter2.getDimensionNames(false);
    int dimCount = dims1.size();
    for (int i = 0; i < dimCount; ++i) {
      final String dim1Name = dim1Names.get(i);
      final String dim2Name = dim2Names.get(i);

      ColumnCapabilities capabilities1 = adapter1.getCapabilities(dim1Name);
      ColumnCapabilities capabilities2 = adapter2.getCapabilities(dim2Name);
      ColumnType dim1Type = capabilities1.toColumnType();
      ColumnType dim2Type = capabilities2.toColumnType();
      if (!Objects.equals(dim1Type, dim2Type)) {
        throw new SegmentValidationException(
            "Dim [%s] types not equal. Expected %d found %d",
            dim1Name,
            dim1Type,
            dim2Type
        );
      }

      Object vals1 = dims1.get(i);
      Object vals2 = dims2.get(i);
      if (isNullRow(vals1) ^ isNullRow(vals2)) {
        throw notEqualValidationException(dim1Name, vals1, vals2);
      }
      boolean vals1IsList = vals1 instanceof List;
      boolean vals2IsList = vals2 instanceof List;
      if (vals1IsList ^ vals2IsList) {
        if (vals1IsList) {
          if (((List) vals1).size() != 1 || !Objects.equals(((List) vals1).get(0), vals2)) {
            throw notEqualValidationException(dim1Name, vals1, vals2);

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Fix the ingestion spec to declare the same explicit dimension type for both segments and re-ingest
  2. Re-persist one segment with dimension conversion (IndexMerger convert) to match the other's column type
  3. Verify with SegmentMetadataQuery which column types differ before validating

Example fix

// before (ingest spec, inconsistent typing)
"dimensions": ["page"]
// after
"dimensions": [{"type": "string", "name": "page"}]
// keep identical declarations in both ingestion specs
Defensive patterns

Strategy: validation

Validate before calling

for (String dim : dims) {
  ColumnType t1 = adapter1.getCapabilities(dim).toColumnType();
  ColumnType t2 = adapter2.getCapabilities(dim).toColumnType();
  if (!Objects.equals(t1, t2)) {
    throw new IllegalStateException("Type mismatch on dim " + dim + ": " + t1 + " vs " + t2);
  }
}

Try / catch

try {
  IndexIO.validateTwoSegments(adapter1, adapter2);
} catch (SegmentValidationException e) {
  if (e.getMessage().contains("types not equal")) {
    // convert one segment's column type before retrying
  }
}

Prevention

When it happens

Trigger: IndexIO.validateTwoSegments on segments where adapter.getCapabilities(dimName).toColumnType() differs for a shared dimension — one segment auto-typed a dimension as numeric while the other kept it as string.

Common situations: Re-ingestion with different auto-detection results (numbers parsed as strings in one run); schema drift after changing ingest spec dimension type declarations; validating segments from different Druid versions with different typing rules.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/b51cffd33a5ed962. Report an issue: GitHub.