apache/druid · error · IllegalStateException
Column[ ] is not a multi-value string column, do not ask…
Error message
Column[%s] is not a multi-value string column, do not ask for a multi-value selector
What it means
A multi-value dimension vector selector can only be built on a column that actually exists and is a dictionary-encoded multi-value STRING column. When the requested column is missing, not string-typed, or single-valued, the factory throws this ISE to catch planning bugs where the vector engine asked for the wrong selector kind.
Solutions
- Confirm the column is ingested as multi-value string (use_json_string_array / MV ingestion) and exists in the segment
- Use a single-value selector/query path for single-valued columns, or use ARRAY functions for typed arrays
- Check the segment schema (segment metadata query) for actual column type; re-ingest if types diverge
- Disable vectorization ('vectorize':'false') as a workaround while fixing the spec
Example fix
// before
factory.makeMultiValueDimensionSelector(DefaultDimensionSpec.of("singleValuedCol"));
// after
factory.makeSingleValueDimensionSelector(DefaultDimensionSpec.of("singleValuedCol")); Defensive patterns
Strategy: validation
Validate before calling
// check segment metadata first
ColumnIngestionPermits/dataset: run segment metadata query and verify capabilities:
boolean ok = holder != null && holder.getCapabilities().isDictionaryEncoded().isMaybeTrue()
&& holder.getCapabilities().is(ValueType.STRING)
&& holder.getCapabilities().hasMultipleValues().isMaybeTrue(); Type guard
boolean isMvString = caps.is(ValueType.STRING) && caps.hasMultipleValues().isMaybeTrue();
Try / catch
try { sel = factory.makeMultiValueDimensionSelector(spec); } catch (IllegalStateException e) { sel = factory.makeSingleValueDimensionSelector(spec); } Prevention
- Enforce consistent column types with an explicit dimensionsSpec at ingest
- Run a segment metadata query to confirm column types before MV-specific queries
- Use ARRAY-typed columns and ARRAY functions for typed arrays instead of MV strings
When it happens
Trigger: Vectorized query calls makeMultiValueDimensionSelector on a single-value string/long column, a non-existent column, or a non-dictionary-encoded column.
Common situations: Auto-detected column type changed between segments (some segments string MV, others long) causing one segment to fail; planning code assuming multi-value based on ingest-time schema; typo'd column name.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Column[ ] is multi-value, do not ask for a single-value…
- Vectorized groupBys on multi-value dictionary-encoded…
- Aggregation [ ] does not support column [ ] of type [ ]…
- Aggregator[ ] cannot vectorize
- Cannot create query type helper from invalid type
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/eec34c8c9ca39c3b.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/vector/QueryableIndexVectorColumnSelectorFactory.java:94
}
@Override
public MultiValueDimensionVectorSelector makeMultiValueDimensionSelector(final DimensionSpec dimensionSpec)
{
if (!dimensionSpec.canVectorize()) {
throw new ISE("DimensionSpec[%s] cannot be vectorized", dimensionSpec);
}
Function<DimensionSpec, MultiValueDimensionVectorSelector> mappingFunction = spec -> {
if (virtualColumns.exists(spec.getDimension())) {
return virtualColumns.makeMultiValueDimensionVectorSelector(dimensionSpec, this, columnSelector, offset);
}
final ColumnHolder holder = columnSelector.getColumnHolder(spec.getDimension());
if (holder == null
|| holder.getCapabilities().isDictionaryEncoded().isFalse()
|| !holder.getCapabilities().is(ValueType.STRING)
|| holder.getCapabilities().hasMultipleValues().isFalse()) {
throw new ISE(
"Column[%s] is not a multi-value string column, do not ask for a multi-value selector",
spec.getDimension()
);
}
@SuppressWarnings("unchecked")
final DictionaryEncodedColumn<String> dictionaryEncodedColumn =
(DictionaryEncodedColumn<String>) holder.getColumn();
// dictionaryEncodedColumn is not null because of holder null check above
assert dictionaryEncodedColumn != null;
final MultiValueDimensionVectorSelector selector = dictionaryEncodedColumn.makeMultiValueDimensionVectorSelector(
offset
);
return spec.decorate(selector);
};
View on GitHub (pinned to 9b90983fd2)