apache/druid · error · java.lang.IllegalStateException

Multi-value row not supported

Error message

Multi-value row not supported

What it means

NestedFieldDictionaryEncodedColumn represents a single scalar nested field, so its vector/single-value accessors assume one value per row. getMultiValueRow() is an unsupported operation for this column type and always throws IllegalStateException: the column cannot hold multi-value rows.

Solutions

  1. Check the column's capabilities (hasMultipleValues/getCardinality/type) before calling getMultiValueRow; use getRow()/get(r) for scalar columns.
  2. Fix type inference or the query path so multi-value APIs are only used on ARRAY-typed columns.
  3. If the field should be multi-valued, re-ingest with the field actually containing arrays so the correct column type is created.

Example fix

// before
IndexedInts vals = column.getMultiValueRow(rowNum);
// after
if (column instanceof NestedFieldDictionaryEncodedColumn) {
  Object v = ((NestedFieldDictionaryEncodedColumn) column).get(rowNum); // scalar path
} else {
  IndexedInts vals = column.getMultiValueRow(rowNum);
}
Defensive patterns

Strategy: type-guard

Validate before calling

// consult column capabilities before choosing the accessor API
boolean multiValue = columnType.isArray() || metadata.hasMultipleValues.get();
IndexedInts vals = multiValue ? column.getMultiValueRow(row) : null;

Type guard

boolean supportsMultiValueRows(BaseColumn col) {
  return !(col instanceof NestedFieldDictionaryEncodedColumn);
}

Try / catch

try {
  vals = col.getMultiValueRow(row);
} catch (IllegalStateException e) {
  if (e.getMessage().equals("Multi-value row not supported")) {
    vals = null; // fall back to scalar get(row)
  } throw e;
}

Prevention

When it happens

Trigger: A query engine or accessor calls getMultiValueRow(int) on a NestedFieldDictionaryEncodedColumn, e.g. generic column-accessor code treating the nested field column as a multi-value capable column.

Common situations: Engine code paths written for ARRAY/multi-value columns invoked on scalar nested fields; custom extensions iterating columns via the multi-value API; mis-typed column inference treating a scalar field as an array.

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/47f7d2820b90fea9. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/segment/nested/NestedFieldDictionaryEncodedColumn.java:154

    return column.size();
  }

  @Override
  public boolean hasMultipleValues()
  {
    return false;
  }

  @Override
  public int getSingleValueRow(int rowNum)
  {
    return column.get(rowNum);
  }

  @Override
  public IndexedInts getMultiValueRow(int rowNum)
  {
    throw new IllegalStateException("Multi-value row not supported");
  }

  @Nullable
  @Override
  public String lookupName(int id)
  {
    final int globalId = dictionary.get(id);
    if (globalId < adjustLongId) {
      return StringUtils.fromUtf8Nullable(globalDictionary.get(globalId));
    } else if (globalId < adjustDoubleId) {
      return String.valueOf(globalLongDictionary.get(globalId - adjustLongId));
    } else if (globalId < adjustArrayId) {
      return String.valueOf(globalDoubleDictionary.get(globalId - adjustDoubleId));
    }
    return null;
  }

  public Object lookupObject(int id)

View on GitHub (pinned to 9b90983fd2)