apache/druid · error · UnsupportedOperationException (UOE)
Unable to get first event timestamp using result format of
Error message
Unable to get first event timestamp using result format of [%s]
What it means
getFirstEventTimestamp only supports RESULT_FORMAT_LIST and RESULT_FORMAT_COMPACTED_LIST. Any other result format has no defined way to extract a first-event timestamp, so it throws an UnsupportedOperationException identifying the unsupported format.
Solutions
- Use list or compacted-list result formats when time-ordering scan results.
- Convert the result value to a supported format before calling getFirstEventTimestamp in custom code.
- If a new result format is needed, extend getFirstEventTimestamp (or upstream it) rather than passing it through.
Example fix
// before
if (sv.getResultFormat() == RESULT_FORMAT_VALUE_VECTOR) { sv.getFirstEventTimestamp(format); }
// after
if (sv.getResultFormat() == RESULT_FORMAT_COMPACTED_LIST || sv.getResultFormat() == RESULT_FORMAT_LIST) {
long ts = sv.getFirstEventTimestamp(sv.getResultFormat());
} Defensive patterns
Strategy: type-guard
Validate before calling
if (format != ResultFormat.RESULT_FORMAT_LIST && format != ResultFormat.RESULT_FORMAT_COMPACTED_LIST) {
throw new IllegalArgumentException("timestamp extraction requires list/compacted-list format");
} Type guard
boolean timestampExtractable(ScanQuery.ResultFormat f) {
return f == ResultFormat.RESULT_FORMAT_LIST || f == ResultFormat.RESULT_FORMAT_COMPACTED_LIST;
} Try / catch
try {
long ts = sv.getFirstEventTimestamp(format);
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("Unable to get first event timestamp")) { /* convert format or skip ordering */ }
else throw e;
} Prevention
- Use list or compacted-list formats for time-ordered scans.
- Don't feed vector/value formats into time-comparison code.
- Extend getFirstEventTimestamp upstream for new formats instead of working around it.
When it happens
Trigger: Calling getFirstEventTimestamp (directly, or via stableLimitingSort/comparison) on a ScanResultValue whose resultFormat is neither list nor compacted-list — e.g. RESULT_FORMAT_VALUE_VECTOR results fed into the time-ordering path.
Common situations: Custom/extension result formats used with time-ordered scans; misconfigured queries whose resultFormat was changed after construction.
Related errors
- Time-ordering on scan queries is only supported for queries…
- Unsupported resultFormat for array-based results
- Aggregator[ ] cannot vectorize
- AppenderatorsManager methods should only called by services…
- ApproximateHistogramBufferAggregator does not support…
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/8881cfbdc8aaf5c2.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/query/scan/ScanResultValue.java:114
public long getFirstEventTimestamp(ScanQuery.ResultFormat resultFormat)
{
if (resultFormat.equals(ScanQuery.ResultFormat.RESULT_FORMAT_LIST)) {
Object timestampObj = ((Map<String, Object>) ((List<Object>) this.getEvents()).get(0)).get(ColumnHolder.TIME_COLUMN_NAME);
if (timestampObj == null) {
throw new ISE("Unable to compare timestamp for rows without a time column");
}
return DimensionHandlerUtils.convertObjectToLong(timestampObj);
} else if (resultFormat.equals(ScanQuery.ResultFormat.RESULT_FORMAT_COMPACTED_LIST)) {
int timeColumnIndex = this.getColumns().indexOf(ColumnHolder.TIME_COLUMN_NAME);
if (timeColumnIndex == -1) {
throw new ISE("Unable to compare timestamp for rows without a time column");
}
List<Object> firstEvent = (List<Object>) ((List<Object>) this.getEvents()).get(0);
return DimensionHandlerUtils.convertObjectToLong(firstEvent.get(timeColumnIndex));
}
throw new UOE("Unable to get first event timestamp using result format of [%s]", resultFormat.toString());
}
public List<ScanResultValue> toSingleEventScanResultValues()
{
List<ScanResultValue> singleEventScanResultValues = new ArrayList<>();
List<Object> events = (List<Object>) this.getEvents();
for (Object event : events) {
singleEventScanResultValues.add(new ScanResultValue(segmentId, columns, Collections.singletonList(event), rowSignature));
}
return singleEventScanResultValues;
}
@Override
public boolean equals(Object o)
{
if (this == o) {
return true;
}View on GitHub (pinned to 9b90983fd2)