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

  1. Flatten the multi-value column before joining (e.g. re-ingest with a single value, or use a transform/maxOf/arrayToString)
  2. Rewrite the query to unnest or explode the multi-value rows first (e.g. UNNEST in SQL)
  3. 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

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


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/30a4bbb1a79388f5. Report an issue: GitHub.