apache/druid · error · IllegalArgumentException (IAE)
Inconsistent number of columns
Error message
Inconsistent number of columns[%d] and columnTypes[%d] specified!
What it means
The ScanQuery constructor validates that if columnTypes is provided, columns must also be provided and both lists must have the same length, since column types are matched positionally to columns. Mismatched sizes throw IAE. This guards the scan query's typed-columns API against ambiguous specs.
Solutions
- Make columns and columnTypes the same length and aligned by position
- Omit columnTypes if you don't need to specify types
- Ensure columns is non-null whenever columnTypes is specified
Example fix
// before columns: ["a","b"], columnTypes: ["LONG"] // after columns: ["a","b"], columnTypes: ["LONG","STRING"]
Defensive patterns
Strategy: validation
Validate before calling
if (columnTypes != null) {
if (columns == null || columns.size() != columnTypes.size()) {
throw new IllegalArgumentException("columns and columnTypes must be same length");
}
} Type guard
boolean scanColumnsConsistent(List<String> columns, List<String> columnTypes) {
return columnTypes == null || (columns != null && columns.size() == columnTypes.size());
} Try / catch
try {
query = new ScanQuery(...);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Inconsistent number of columns")) {
query = rebuildScanQueryAligned();
} else throw e;
} Prevention
- Build columns and columnTypes in the same loop so they stay aligned
- Omit columnTypes unless typed columns are explicitly needed
When it happens
Trigger: Constructing ScanQuery (directly or via query JSON) where columns.size() != columnTypes.size(), or columnTypes set while columns is null.
Common situations: Hand-edited query JSON adding a type without the matching column; programmatic query building where the two lists are populated by different code paths.
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
- 'skip' must be greater than zero
- Aggregation [ ] does not support column [ ] of type [ ]…
- An inline input source must provide one or more columns
- argument should be an identifier expression. Use array()…
- Cannot apply limit[ ] with offset[ ] due to overflow
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/f3495bb6137a68a2.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/query/scan/ScanQuery.java:163
);
this.scanRowsOffset = scanRowsOffset;
Preconditions.checkArgument(
this.scanRowsOffset >= 0,
"offset must be greater than or equal to 0"
);
this.scanRowsLimit = (scanRowsLimit == 0) ? Long.MAX_VALUE : scanRowsLimit;
Preconditions.checkArgument(
this.scanRowsLimit > 0,
"limit must be greater than 0"
);
this.dimFilter = dimFilter;
this.columns = columns;
this.columnTypes = columnTypes;
if (columnTypes != null) {
Preconditions.checkNotNull(columns, "columns may not be null if columnTypes are specified");
if (columns.size() != columnTypes.size()) {
throw new IAE(
"Inconsistent number of columns[%d] and columnTypes[%d] specified!",
columns.size(),
columnTypes.size()
);
}
}
final Pair<List<OrderBy>, Order> ordering = verifyAndReconcileOrdering(orderBysFromUser, orderFromUser);
this.orderBys = Preconditions.checkNotNull(ordering.lhs);
this.timeOrder = ordering.rhs;
if (this.columns != null && this.columns.size() > 0) {
// Validate orderBy. (Cannot validate when signature is empty, since that means "discover at runtime".)
for (final OrderBy orderByColumn : this.orderBys) {
if (!this.columns.contains(orderByColumn.getColumnName())) {
// Error message depends on how the user originally specified ordering.
if (orderBysFromUser != null) {View on GitHub (pinned to 9b90983fd2)