apache/druid · error · QueryUnsupportedException
Joining against a multi-value dimension is not supported.
Error message
Joining against a multi-value dimension is not supported.
What it means
The lookup join matcher reads single values from the right-hand lookup dimension per row. If a row contains multiple values (multi-value dimension), the join system cannot produce a single key, so it throws QueryUnsupportedException. Druid does not support joining against multi-value dimensions (issue #9924).
Source
Thrown at processing/src/main/java/org/apache/druid/segment/join/lookup/LookupJoinMatcher.java:80
public ColumnType defaultType()
{
return ColumnType.STRING;
}
@Override
public Supplier<String> makeDimensionProcessor(DimensionSelector selector, boolean multiValue)
{
return () -> {
final IndexedInts row = selector.getRow();
if (row.size() == 1) {
return selector.lookupName(row.get(0));
} else if (row.size() == 0) {
return null;
} else {
// Multi-valued rows are not handled by the join system right now
// TODO: Remove when https://github.com/apache/druid/issues/9924 is done
throw new QueryUnsupportedException("Joining against a multi-value dimension is not supported.");
}
};
}
@Override
public Supplier<String> makeFloatProcessor(BaseFloatColumnValueSelector selector)
{
return () -> selector.isNull() ? null : DimensionHandlerUtils.convertObjectToString(selector.getFloat());
}
@Override
public Supplier<String> makeDoubleProcessor(BaseDoubleColumnValueSelector selector)
{
return () -> selector.isNull() ? null : DimensionHandlerUtils.convertObjectToString(selector.getDouble());
}
@Override
public Supplier<String> makeLongProcessor(BaseLongColumnValueSelector selector)View on GitHub (pinned to 9b90983fd2)
Solutions
- Flatten the multi-value column before joining (e.g. re-ingest with a single value, or use a transform/maxOf/arrayToString)
- Rewrite the query to unnest or explode the multi-value rows first (e.g. UNNEST in SQL)
- Change the ingestion spec so the join key column is always single-valued
Example fix
// before: join on multi-valued column 'tags' // after: SQL SELECT ... FROM t JOIN lookup ON t.country = lookup.k -- ensure 'country' is single-valued, e.g. via UNNEST or re-ingestion
Defensive patterns
Strategy: type-guard
Validate before calling
ColumnCapabilities caps = selectorFactory.getColumnCapabilities(keyColumn);
if (caps != null && caps.hasMultipleValues().isTrue()) throw new IllegalArgumentException("join key is multi-valued"); Type guard
boolean isSingleValued(ColumnCapabilities caps) { return caps == null || !caps.hasMultipleValues().isTrue(); } Try / catch
try { runJoin(query); } catch (QueryUnsupportedException e) { if (e.getMessage().contains("multi-value")) { /* flatten and retry */ } } Prevention
- Check column capabilities (hasMultipleValues) before planning lookup joins
- Flatten multi-value dimensions at ingestion with transforms or aggregator like 'maxOf'
- Enable automatic multi-value flattening in your query-builder layer
When it happens
Trigger: Executing a join (e.g. SQL join to a lookup) whose right-hand side column is a multi-value string dimension, and the matcher encounters a row with row.size() > 1.
Common situations: Ingested data where the lookup key column ended up multi-valued (e.g. array-like input split on a delimiter); joining on a column that was auto-detected as multi-valued.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Joining against a ARRAY columns is not supported.
- Cannot join lookup with non-equi condition: %s
- Cannot join lookup with condition referring to non-key colum
- Column[%s] does not start with prefix[%s]
- Detected duplicate prefix in join clauses: [%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/30a4bbb1a79388f5.
Report an issue: GitHub.