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
- Fix the ingestion spec to declare the same explicit dimension type for both segments and re-ingest
- Re-persist one segment with dimension conversion (IndexMerger convert) to match the other's column type
- 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
- Declare explicit dimension types in ingestion specs to avoid auto-detection drift
- Compare column capabilities with a SegmentMetadataQuery before merging/validating
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
- Aggregation [%s] does not support column [%s] of type [%s].
- Actual Row count mismatch. Expected [%d] found [%d]
- Dim lengths not equal %s vs %s
- Cannot accept both 'splitPoints' and 'numBins'
- at least 2 bins expected
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/b51cffd33a5ed962.
Report an issue: GitHub.