apache/druid · error · IllegalStateException

Cannot return long for Null Value

Error message

Cannot return long for Null Value

What it means

The long variant of the null-guard in NullableNumericAggregateCombiner: getLong() returns a primitive long that cannot represent SQL NULL, so when the tracked combined result is null it throws IllegalStateException instead of returning a default. Callers must test isNull() first or use the nullable getObject().

Source

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

      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();
  }

  @Nullable
  @Override
  public T getObject()
  {
    return isNullResult ? null : delegate.getObject();
  }

  @Override

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Guard with combiner.isNull() before calling getLong() and emit a nullable Long (or skip the value) when true.
  2. Use getObject() to receive a boxed Long that is null instead of an exception.
  3. Enable druid.generic.useDefaultValueForNull=true or use COALESCE in the SQL query if null semantics must be flattened to 0.
  4. Update custom result extraction code to be null-aware for all primitive accessors (getFloat/getDouble/getLong).

Example fix

// before
long value = combiner.getLong();
// after
Long value = combiner.isNull() ? null : combiner.getLong();
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 Long safeGetLong(AggregateCombiner<?> combiner) {
  return combiner.isNull() ? null : combiner.getLong();
}

Try / catch

try {
  long v = combiner.getLong();
} 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 getLong() while isNullResult is true — reset() saw a null selector and no non-null value has been folded in — typically in queries with SQL-compatible null handling where all rows contributing to the group contained null for the aggregated column.

Common situations: Long-typed aggregators (e.g. longSum) over an entirely null group read by custom extraction code; COUNT/SUM result handling written assuming primitive defaults; extension aggregator implementations built on AggregateCombiner that ignore the null-aware wrapper.

Related errors


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