apache/druid · error · IllegalStateException

Cannot return double for Null Value

Error message

Cannot return double for Null Value

What it means

Same mechanism as the float variant: NullableNumericAggregateCombiner tracks a null combined result and getDouble() must return a primitive double, which cannot encode null. It throws IllegalStateException rather than silently returning 0.0. The caller is required to check isNull() first.

Source

Thrown at processing/src/main/java/org/apache/druid/query/aggregation/NullableNumericAggregateCombiner.java:85

        delegate.fold(selector);
      }
    }
  }

  @Override
  public float getFloat()
  {
    if (isNullResult) {
      throw new IllegalStateException("Cannot return primitive float for Null Value");
    }
    return delegate.getFloat();
  }

  @Override
  public double getDouble()
  {
    if (isNullResult) {
      throw new IllegalStateException("Cannot return double for Null Value");
    }
    return delegate.getDouble();
  }

  @Override
  public long getLong()
  {
    if (isNullResult) {
      throw new IllegalStateException("Cannot return long for Null Value");
    }
    return delegate.getLong();
  }

  @Override
  public boolean isNull()
  {
    return isNullResult || delegate.isNull();
  }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Check combiner.isNull() (or selector.isNull()) before calling getDouble() and represent the result as a nullable Double.
  2. Prefer getObject() which returns null instead of throwing for null results.
  3. Enable druid.generic.useDefaultValueForNull=true or wrap the expression in COALESCE if the consumer cannot represent null.
  4. Audit custom accessors/serializers to handle null-aware combiners added with SQL null handling.

Example fix

// before
double value = combiner.getDouble();
// after
Double value = combiner.isNull() ? null : combiner.getDouble();
Defensive patterns

Strategy: type-guard

Validate before calling

// call-site guard: never read primitives from a null-aware combiner unchecked
if (combiner.isNull()) {
  return null; // or sentinel per your result model
}

Type guard

static Double safeGetDouble(AggregateCombiner<?> combiner) {
  return combiner.isNull() ? null : combiner.getDouble();
}

Try / catch

try {
  double v = combiner.getDouble();
} catch (IllegalStateException e) {
  if (e.getMessage() != null && e.getMessage().contains("Null Value")) {
    // treat as SQL NULL
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling getDouble() while isNullResult is true — after reset() on a null selector value with no non-null fold() since — in a query where SQL-compatible null handling (druid.generic.useDefaultValueForNull=false) is enabled and every input value in the group was null.

Common situations: All-null groups for a SUM/AVG-style aggregator read through a custom result accessor; extension code that copies combiner values into result rows assuming non-null primitives; result-format or type-conversion paths written before null-aware combiners were introduced.

Related errors


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