apache/druid · error · IllegalStateException

FLOAT types are not supported natively by Druid expressions

Error message

FLOAT types are not supported natively by Druid expressions

What it means

The Druid expression system has no native FLOAT representation — it folds all floating point into DOUBLE. ExpressionTypeFactory.ofFloat() (the TypeFactory<ExpressionType> implementation) therefore unconditionally throws IllegalStateException to signal that FLOAT cannot be used as an expression type.

Source

Thrown at processing/src/main/java/org/apache/druid/math/expr/ExpressionTypeFactory.java:56

  {
    return INSTANCE;
  }

  private ExpressionTypeFactory()
  {
    // no instantiation
  }

  @Override
  public ExpressionType ofString()
  {
    return ExpressionType.STRING;
  }

  @Override
  public ExpressionType ofFloat()
  {
    throw new IllegalStateException("FLOAT types are not supported natively by Druid expressions");
  }

  @Override
  public ExpressionType ofDouble()
  {
    return ExpressionType.DOUBLE;
  }

  @Override
  public ExpressionType ofLong()
  {
    return ExpressionType.LONG;
  }

  @Override
  public ExpressionType ofArray(ExpressionType elementType)
  {
    if (elementType.isPrimitive()) {

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Use ofDouble() instead — FLOAT columns are already promoted to DOUBLE by fromColumnType/fromColumnTypeStrict.
  2. Route ValueType.FLOAT through ExpressionType.DOUBLE in your conversion code rather than calling ofFloat().
  3. Call ColumnType.ofFloat()/TypeFactory for column types if you truly need FLOAT, keeping it out of the expression layer.
  4. Catch IllegalStateException and substitute ExpressionType.DOUBLE as a fallback.

Example fix

// before
ExpressionType t = ExpressionTypeFactory.getInstance().ofFloat();
// after
ExpressionType t = ExpressionTypeFactory.getInstance().ofDouble(); // expressions treat FLOAT as DOUBLE
Defensive patterns

Strategy: type-guard

Validate before calling

if (valueType == ValueType.FLOAT) {
  ExpressionType t = ExpressionType.DOUBLE; // expressions have no FLOAT
} else {
  ExpressionType t = fromValue(valueType);
}

Type guard

boolean isFloatValue(ValueType t) { return t == ValueType.FLOAT; }

Try / catch

try {
  ExpressionType t = factory.ofFloat();
} catch (IllegalStateException e) {
  ExpressionType t = ExpressionType.DOUBLE;
}

Prevention

When it happens

Trigger: Calling ExpressionTypeFactory.getInstance().ofFloat(), or generic code that iterates TypeFactory methods / ValueType values and invokes ofFloat() when building expression types from a ValueType.FLOAT.

Common situations: Generic type-conversion code that maps each ValueType via the factory instead of special-casing FLOAT; extensions or tests written against the TypeFactory interface assuming all value types are supported; upgrading code paths that previously used floats.

Related errors


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