apache/druid · error · SegmentValidationException
Dim [ ] values not equal. Expected found
Error message
Dim [%s] values not equal. Expected %s found %s
What it means
IndexIO.validateTwoSegments compares corresponding rows/columns of two segments and throws a ValidationException 'Dim [%s] values not equal. Expected %s found %s' when a dimension's null-ness differs between the two segments for the same row. Here exactly one of the two values is a null row (isNullRow XOR). This guard detects segment corruption or divergence between replicas/converted segments.
Solutions
- Re-ingest or re-generate the segment from source data.
- Compare against the correct counterpart segment; verify you validated the intended pair.
- Check for segment corruption with the segment's metadata/hash and restore from deep storage.
Example fix
// before indexIO.validateTwoSegments(expectedSegment, convertedSegment); // after // regenerate the mismatching segment instead of validating Segment fixed = segmentCreator.buildFromSource(sourceData); indexIO.validateTwoSegments(expectedSegment, fixed);
Defensive patterns
Strategy: validation
Validate before calling
// pre-check null-ness parity before validation
boolean nullParity = isNullRow(vals1) == isNullRow(vals2);
if (!nullParity) { regenerateSegment(); } Try / catch
try { indexIO.validateTwoSegments(a, b); } catch (ValidationException e) { log.error("Segment mismatch: {}", e.getMessage()); regenerateFromSource(); } Prevention
- Always validate segments against a trusted counterpart from the same ingestion run.
- Restore suspicious segments from deep storage before validation.
- Pin the same Druid version for segment conversion and validation.
When it happens
Trigger: Running validateTwoSegments (e.g. segment conversion validation, replacement validation) where at row i for dimension i, one segment holds a null row and the other holds a non-null value.
Common situations: Verifying segments after Druid version upgrades or index conversion; comparing replaced/historical segments; corrupted partial data written by a buggy ingestion run.
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
- A-Not-B requires at least 1 sketch
- Access-Check-Result
- Action [ ] failed for worker [ ] with status ( )
- Actual Row count mismatch. Expected
- Aggregation [ ] does not support column [ ] of type [ ]…
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/da401e5024dcf2bb.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/IndexIO.java:283
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);
}
} else {
if (((List) vals2).size() != 1 || !Objects.equals(((List) vals2).get(0), vals1)) {
throw notEqualValidationException(dim1Name, vals1, vals2);
}
}
} else if (vals1 instanceof Object[]) {
if (!Arrays.deepEquals((Object[]) vals1, (Object[]) vals2)) {
throw notEqualValidationException(dim1Name, vals1, vals2);
}
} else {View on GitHub (pinned to 9b90983fd2)