apache/druid · error · IllegalStateException
Cannot return long for Null Value
Error message
Cannot return long for Null Value
What it means
NullableNumericBufferAggregator keeps a null-marker byte in the ByteBuffer in front of each long value. getLong() throws IllegalStateException when that marker is IS_NULL_BYTE because a primitive long cannot represent null (0L would be ambiguous with a real zero).
Source
Thrown at processing/src/main/java/org/apache/druid/query/aggregation/NullableNumericBufferAggregator.java:102
return null;
}
return delegate.get(buf, position + Byte.BYTES);
}
@Override
public float getFloat(ByteBuffer buf, int position)
{
if (buf.get(position) == TypeStrategies.IS_NULL_BYTE) {
throw new IllegalStateException("Cannot return float for Null Value");
}
return delegate.getFloat(buf, position + Byte.BYTES);
}
@Override
public long getLong(ByteBuffer buf, int position)
{
if (buf.get(position) == TypeStrategies.IS_NULL_BYTE) {
throw new IllegalStateException("Cannot return long for Null Value");
}
return delegate.getLong(buf, position + Byte.BYTES);
}
@Override
public double getDouble(ByteBuffer buf, int position)
{
if (buf.get(position) == TypeStrategies.IS_NULL_BYTE) {
throw new IllegalStateException("Cannot return double for Null Value");
}
return delegate.getDouble(buf, position + Byte.BYTES);
}
@Override
public boolean isNull(ByteBuffer buf, int position)
{
return buf.get(position) == TypeStrategies.IS_NULL_BYTE || delegate.isNull(buf, position + Byte.BYTES);
}View on GitHub (pinned to 9b90983fd2)
Solutions
- Check agg.isNull(buf, position) before calling getLong()
- Verify delegate reads use position + Byte.BYTES so the value, not the flag byte, is decoded
- Ensure init()/putNull() in TypeStrategies initialize the marker byte for new group positions
- If a group unexpectedly has no non-null values, that is a legitimate null result — handle it upstream instead of forcing a read
Example fix
// before long v = agg.getLong(buf, position); // after Long v = agg.isNull(buf, position) ? null : agg.getLong(buf, position);
Defensive patterns
Strategy: validation
Validate before calling
if (agg.isNull(buf, position)) {
return null;
} Try / catch
try {
return agg.getLong(buf, position);
} catch (IllegalStateException e) {
if (e.getMessage().contains("Cannot return long for Null Value")) {
return null;
}
throw e;
} Prevention
- Always read the marker byte at `position` and the value at position + Byte.BYTES — mixing up offsets corrupts both flag and value
- Ensure init() writes IS_NULL_BYTE (or a valid marker) for every allocated slot
- Audit custom buffer aggregators for the nullable wrapper's buffer protocol
- Handle legitimate null groups in extraction code instead of forcing primitive reads
When it happens
Trigger: Calling getLong(buf, position) when the byte at `position` is TypeStrategies.IS_NULL_BYTE — the group never aggregated a non-null long value.
Common situations: Long aggregations in group-by queries where some groups have only null inputs; buffer layout bugs where reads don't skip the flag byte (position vs position + Byte.BYTES); custom aggregators integrated without the nullable wrapper's buffer protocol.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Cannot return float for Null Value
- Cannot return double for Null Value
- Cannot return float for Null Value
- Cannot return long for Null Value
- Cannot return double for Null Value
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/43e652eddb87258f.
Report an issue: GitHub.