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
- Check combiner.isNull() (or selector.isNull()) before calling getDouble() and represent the result as a nullable Double.
- Prefer getObject() which returns null instead of throwing for null results.
- Enable druid.generic.useDefaultValueForNull=true or wrap the expression in COALESCE if the consumer cannot represent null.
- 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
- Check isNull() before every primitive getter on AggregateCombiner implementations.
- Use boxed accessors (getObject) for code paths that must model SQL NULL.
- Test aggregations over all-null groups explicitly when null handling is SQL-compatible.
- COALESCE in SQL or enable default-value-for-null mode if nulls must be flattened.
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
- Cannot return primitive float for Null Value
- Cannot return long for Null Value
- Emit called unexpectedly before service start
- Got an exception while parsing file [%s]
- Unable to copy key [%s] to file [%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/9ebd72fb3c5c2671.
Report an issue: GitHub.