apache/druid · error · java.lang.UnsupportedOperationException
StringFirstAggregator does not support getFloat()
Error message
StringFirstAggregator does not support getFloat()
What it means
StringFirstAggregator computes the earliest string value per group; its result type is a string (wrapped in a SerializablePairLongString), not numeric. getFloat() is therefore unsupported and always throws UnsupportedOperationException. Queries or post-aggregations requesting a float from this aggregator are invalid.
Source
Thrown at processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstAggregator.java:95
if (time < firstTime) {
final String value = DimensionHandlerUtils.convertObjectToString(valueSelector.getObject());
firstTime = time;
firstValue = StringUtils.fastLooseChop(value, maxStringBytes);
}
}
}
@Override
public Object get()
{
return new SerializablePairLongString(firstTime, StringUtils.chop(firstValue, maxStringBytes));
}
@Override
public float getFloat()
{
throw new UnsupportedOperationException("StringFirstAggregator does not support getFloat()");
}
@Override
public long getLong()
{
throw new UnsupportedOperationException("StringFirstAggregator does not support getLong()");
}
@Override
public double getDouble()
{
throw new UnsupportedOperationException("StringFirstAggregator does not support getDouble()");
}
@Override
public void close()
{
// no resources to cleanupView on GitHub (pinned to 9b90983fd2)
Solutions
- Do not call getFloat(); use the aggregator's string result via the proper getter/serialized form.
- Remove any post-aggregator or outputType that treats stringFirst output as numeric.
- Use a numeric-first/last aggregator (e.g. FloatFirst/DoubleFirst) if a numeric earliest value is needed.
- Wrap the access with a type check on the aggregator's result type before invoking numeric getters.
Example fix
// before
AggregatorFactory first = new StringFirstAggregatorFactory("f", "col", null, null);
float v = ((BufferAggregator) agg).getFloat(buf, pos);
// after
Object v = ((StringFirstBufferAggregator) agg).get(buf, pos); // string pair, not float Defensive patterns
Strategy: type-guard
Validate before calling
if (aggregator instanceof StringFirstAggregator) {
Object v = aggregator.get(); // string pair
} else {
float v = aggregator.getFloat();
} Type guard
boolean hasNumericResult(Aggregator a) {
return !(a instanceof StringFirstAggregator);
} Try / catch
try {
return agg.getFloat();
} catch (UnsupportedOperationException e) {
Object pair = agg.get();
return pair == null ? 0f : Float.parseFloat(String.valueOf(((SerializablePairLongString) pair).rhs));
} Prevention
- Never configure numeric outputType on stringFirst.
- Read string-first results via get().
- Use dedicated numeric first/last aggregators for numbers.
When it happens
Trigger: Accessing getFloat() on a StringFirstAggregator result — typically a finalizing/post-aggregation step treating the string-first output as a float, or a factory contract calling numeric getters unconditionally.
Common situations: Writing a custom post-aggregator over stringFirst output, using stringFirst with an outputType of float/long, or framework code iterating numeric getters on an aggregator buffer.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- StringFirstAggregator does not support getLong()
- StringFirstAggregator does not support getDouble()
- StringFirstAggregator does not support getFloat()
- StringFirstAggregator does not support getLong()
- StringFirstAggregator does not support getDouble()
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/a20e5b8e91128b7d.
Report an issue: GitHub.