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.

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.

Appendix: 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)