apache/druid · error · SegmentValidationException

Dim lengths not equal %s vs %s

Error message

Dim lengths not equal %s vs %s

What it means

During IndexIO.validateRowValues, each row's dimension value list from the two segments is compared element-by-element. If the two rows have a different number of dimension values, validation fails before the per-dimension comparison can run. This signals structurally different rows, usually from segments built with different schemas or null-handling.

Source

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

  private static void validateRowValues(
      RowPointer rp1,
      IndexableAdapter adapter1,
      RowPointer rp2,
      IndexableAdapter adapter2
  )
  {
    if (rp1.getTimestamp() != rp2.getTimestamp()) {
      throw new SegmentValidationException(
          "Timestamp mismatch. Expected %d found %d",
          rp1.getTimestamp(),
          rp2.getTimestamp()
      );
    }
    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

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Align ingestion specs so both segments have identical dimension schemas and null handling
  2. Re-persist the segment with the schema of the reference segment (use IndexMerger with explicit dim exclusions/convert)
  3. Upgrade both segments to the same Druid version so null-dimension encoding matches
Defensive patterns

Strategy: validation

Validate before calling

List<Object> d1 = rp1.getDimensionValuesForDebug();
List<Object> d2 = rp2.getDimensionValuesForDebug();
if (d1.size() != d2.size()) {
  throw new IllegalStateException("Row dim counts differ: " + d1.size() + " vs " + d2.size());
}

Try / catch

try {
  IndexIO.validateTwoSegments(adapter1, adapter2);
} catch (SegmentValidationException e) {
  if (e.getMessage().startsWith("Dim lengths not equal")) {
    // schema mismatch: rebuild segment with matching schema
  }
}

Prevention

When it happens

Trigger: Running IndexIO.validateTwoSegments on segments whose rows report different getDimensionValuesForDebug() list sizes — e.g. one segment has null/unset dimensions encoded differently than the other.

Common situations: Comparing segments built by different Druid versions with different default null dimension handling; validating a segment against a re-ingested copy where schema auto-discovery found extra dimensions.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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