apache/druid · error · UnsupportedOperationException (UOE)

VALUE_VECTOR is not supported yet

Error message

VALUE_VECTOR is not supported yet

What it means

ScanQueryLimitRowIterator.next() explicitly rejects RESULT_FORMAT_VALUE_VECTOR, throwing UOE, because limiting logic is not implemented for the vectorized value format. It is checked before any limiting work begins.

Solutions

  1. Change resultFormat to "compactedList" or "list"
  2. Remove the valueVector setting until the format is supported
  3. Drop the limit/offset if a custom path can consume valueVector directly

Example fix

// before
{"queryType":"scan","resultFormat":"valueVector","limit":100,...}
// after
{"queryType":"scan","resultFormat":"list","limit":100,...}
Defensive patterns

Strategy: validation

Validate before calling

if (query.getResultFormat() == ScanQuery.ResultFormat.RESULT_FORMAT_VALUE_VECTOR) {
  throw new IllegalArgumentException("valueVector is unsupported for limited scans");
}

Type guard

boolean limitableFormat(ScanQuery q) { return q.getResultFormat() != ScanQuery.ResultFormat.RESULT_FORMAT_VALUE_VECTOR; }

Try / catch

try {
  return limitIterator.next();
} catch (UnsupportedOperationException e) {
  // re-run with list/compactedList format
}

Prevention

When it happens

Trigger: Running a scan query with resultFormat=valueVector through the path wrapped by ScanQueryLimitRowIterator (any query with a limit/offset that must be applied by this iterator).

Common situations: Testing newer vectorized scan formats not yet supported; tooling that sets resultFormat=valueVector programmatically for performance reasons.

Related errors


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

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/query/scan/ScanQueryLimitRowIterator.java:98

          {
            this.yield();
            return in;
          }
        }
    );
  }

  @Override
  public boolean hasNext()
  {
    return !yielder.isDone() && count < limit;
  }

  @Override
  public ScanResultValue next()
  {
    if (ScanQuery.ResultFormat.RESULT_FORMAT_VALUE_VECTOR.equals(resultFormat)) {
      throw new UOE(ScanQuery.ResultFormat.RESULT_FORMAT_VALUE_VECTOR + " is not supported yet");
    }

    // We want to perform multi-event ScanResultValue limiting if we are not time-ordering or are at the
    // inner-level if we are time-ordering
    if (query.getTimeOrder() == Order.NONE ||
        !query.context().getBoolean(ScanQuery.CTX_KEY_OUTERMOST, true)) {
      ScanResultValue batch = yielder.get();
      List events = (List) batch.getEvents();
      if (events.size() <= limit - count) {
        count += events.size();
        yielder = yielder.next(null);
        return batch;
      } else {
        // last batch
        // single batch length is <= Integer.MAX_VALUE, so this should not overflow
        int numLeft = (int) (limit - count);
        count = limit;
        return new ScanResultValue(

View on GitHub (pinned to 9b90983fd2)