apache/druid · error · IllegalStateException (ISE)
Mismatch in expected[%d] vs actual[%s] field count
Error message
Mismatch in expected[%d] vs actual[%s] field count
What it means
ScanQuery's result format mapper converts each result row into an array of values aligned with the query's requested field list. If a row's value count does not match the expected number of fields, Druid throws this IllegalStateException because the row cannot be safely remapped positionally.
Source
Thrown at processing/src/main/java/org/apache/druid/query/scan/ScanQueryQueryToolChest.java:299
for (int i = 0; i < fields.size(); i++) {
rowArray[i] = row.get(fields.get(i));
}
return rowArray;
};
break;
case RESULT_FORMAT_COMPACTED_LIST:
mapper = (List<Object> row) -> {
if (row.size() == fields.size()) {
return row.toArray();
} else if (fields.isEmpty()) {
return new Object[0];
} else {
// Uh oh... mismatch in expected and actual field count. I don't think this should happen, so let's
// throw an exception. If this really does happen, and there's a good reason for it, then we should remap
// the result row here.
throw new ISE("Mismatch in expected[%d] vs actual[%s] field count", fields.size(), row.size());
}
};
break;
default:
throw new UOE("Unsupported resultFormat for array-based results: %s", resultFormat);
}
return mapper;
}
}
View on GitHub (pinned to 9b90983fd2)
Solutions
- Ensure the ScanQuery's columns list matches the actual columns of every segment being scanned (or query with an empty/consistent column list so results are self-describing).
- Re-run the scan against a consistent set of segments, or compact/reindex segments so all share the same schema.
- If the mismatch is legitimate, remap the result row in a custom resultFormat mapper rather than relying on the default one.
- Check for custom extensions or intermediary operators that alter row arity between the query and the format mapper.
Example fix
// before: query built with stale columns
ScanQuery q = new ScanQuery(..., Arrays.asList("col1","col2"), ...);
// after: use null columns to derive fields from segment schema, or fix the list
ScanQuery q = new ScanQuery(..., null /* all columns */, ...); Defensive patterns
Strategy: validation
Validate before calling
if (row.size() != fields.size()) {
throw new IllegalArgumentException("Scan row field count " + row.size() + " != expected " + fields.size());
} Type guard
boolean fieldsMatch(ScanResultValue sv, List<String> fields) { return sv.getEvents() instanceof List && fields != null; } Try / catch
try {
Sequence<Object[]> rows = mapper.apply(resultValue);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Mismatch in expected")) { /* re-query with consistent columns */ }
else throw e;
} Prevention
- Keep the query columns list null (all columns) or keep it in sync with segment schema.
- Compact segments after schema changes so all segments share columns.
- Never mutate ScanResultValue.events without updating columns.
When it happens
Trigger: Calling resultsAsFrames or the row mapper (e.g. via Sequences.map on scan results) when a ScanResultValue row contains a different number of values than the fields listed in the ScanQuery's columns list; typically after schema changed mid-scan or custom code built a ScanResultValue with mismatched columns/events.
Common situations: Segment schema drift (columns added/removed between segments scanned in one query), manually constructing ScanResultValues in tests/tools, or custom QueryToolChest extensions feeding rows with stale column lists.
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
- Column [%s] from 'orderBy' must also appear in 'columns'.
- The __time column must be selected if the results are time-o
- Cannot execute query with orderBy %s
- Cannot provide 'order' incompatible with 'orderBy'
- Null cursor factory found. Probably trying to issue a query
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/0e02cbae242ffe3c.
Report an issue: GitHub.