apache/druid · error · java.lang.IllegalArgumentException

not a scalar in the dictionary

Error message

not a scalar in the dictionary

What it means

This error comes from a dictionary-lookup helper in VariantColumn (the dictionary-encoded variant column variant) that maps an id to a string, long, or double. If the id exceeds all scalar sub-dictionary ranges (including the array adjust bound), it cannot correspond to any scalar dictionary entry, so it throws IllegalArgumentException 'not a scalar in the dictionary'.

Solutions

  1. Regenerate or re-ingest the segment to rebuild consistent dictionaries
  2. Confirm reader and writer Druid versions match for the segment format (V1 nested columns)
  3. Check for array ids being passed into scalar-only lookup paths and route them to the array dictionary
  4. Validate segment dictionaries for corruption

Example fix

// before
Object v = scalarLookup(id); // id >= adjustArrayId
// after
if (id < adjustArrayId) { Object v = scalarLookup(id); } else { /* array path */ }
Defensive patterns

Strategy: validation

Validate before calling

if (id >= adjustArrayId) { /* id refers to array dictionary, not scalars */ }

Type guard

static boolean isScalarId(int id, int adjustArrayId) { return id >= 0 && id < adjustArrayId; }

Try / catch

try { Object v = lookup(id); } catch (IllegalArgumentException e) { if (e.getMessage().contains("not a scalar")) { /* route to array dictionary */ } else { throw e; } }

Prevention

When it happens

Trigger: Looking up an id beyond the string+long+double dictionary sizes in a dictionary-encoded variant column, typically because the id belongs to an array entry or is stale/corrupt.

Common situations: Vectorized or row queries resolving ids for a mixed-type variant column where array ids leaked into a scalar lookup; segments written with a different dictionary layout than the reader expects (version mismatch).

Related errors


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

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/segment/nested/VariantColumn.java:930

    if (variantTypes == null) {
      return lookupScalarValue(id);
    } else {
      ExprEval eval = ExprEval.ofType(logicalExpressionType, lookupScalarValue(id));
      return eval.value();
    }
  }

  @Nullable
  private Object lookupScalarValue(int id)
  {
    if (id < adjustLongId) {
      return StringUtils.fromUtf8Nullable(stringDictionary.get(id));
    } else if (id < adjustDoubleId) {
      return longDictionary.get(id - adjustLongId);
    } else if (id < adjustArrayId) {
      return doubleDictionary.get(id - adjustDoubleId);
    }
    throw new IllegalArgumentException("not a scalar in the dictionary");
  }

  /**
   * Make a {@link VectorObjectSelector} for a dictionary encoded column that coerces mixed types to a common type
   */
  public abstract static class VariantVectorObjectSelector implements VectorObjectSelector
  {
    private final int[] vector;
    private final Object[] objects;
    private int offsetId = ReadableVectorInspector.NULL_ID;
    private final ReadableVectorOffset offset;
    private final ColumnarInts encodedValueColumn;
    private final FrontCodedIntArrayIndexed arrayDictionary;
    private final ExpressionType logicalExpressionType;
    private final int adjustArrayId;

    protected VariantVectorObjectSelector(
        ReadableVectorOffset offset,

View on GitHub (pinned to 9b90983fd2)