apache/druid · error · IllegalStateException (ISE)
Row came from an unscanned interval
Error message
Row came from an unscanned interval
What it means
While draining the priority queue in stableLimitingSort, each emitted row's timestamp must fall inside one of the intervals the query declared it was scanning. A row whose timestamp matches no interval means the interval bookkeeping desynchronized from the data, so Druid throws this IllegalStateException.
Solutions
- Verify the query's intervals/segment descriptors actually cover all rows' timestamps in the targeted segments.
- Reindex the offending segments so row timestamps match their shard intervals.
- Check for custom code building MultipleSpecificSegmentSpec with incorrect per-segment intervals.
- If caused by data/ingestion misalignment, fix the ingestion granularity and compact the affected segments.
Defensive patterns
Strategy: validation
Validate before calling
if (query.getIntervals() != null) {
for (Interval iv : query.getQuerySegmentSpec().getIntervals(query)) {
// confirm segment min/max time falls within iv
}
} Try / catch
try {
results = runner.run(QueryPlus.wrap(query), ctx).toList();
} catch (IllegalStateException e) {
if (e.getMessage().equals("Row came from an unscanned interval")) { /* widen intervals or reindex segments */ }
else throw e;
} Prevention
- Ensure query intervals cover the full timestamp range of targeted segments.
- Fix ingestion so row timestamps match shard intervals; compact misaligned segments.
- Validate custom MultipleSpecificSegmentSpec construction.
When it happens
Trigger: mergeRunners with time-ordering where the yielder returns a row whose event time is not contained by any interval in intervalsOrdered — e.g. intervals in the query spec do not actually cover the segment data's timestamps, or segment/intervals pairs were assembled incorrectly.
Common situations: Queries with MultipleSpecificSegmentSpec built by custom code where descriptor intervals were computed wrongly; data written outside the segment's declared interval (granularity misalignment); clock/timezone issues causing timestamps outside shard intervals.
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 apply limit[ ] with offset[ ] due to overflow
- Cannot execute query with orderBy
- Cannot provide 'order' incompatible with 'orderBy'
- Column [ ] from 'orderBy' must also appear in 'columns'.
- Got a [ ] which isn't a
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/446659b0fa8f420d.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/query/scan/ScanQueryRunnerFactory.java:259
while (!doneScanning) {
ScanResultValue next = yielder.get();
List<ScanResultValue> singleEventScanResultValues = next.toSingleEventScanResultValues();
for (ScanResultValue srv : singleEventScanResultValues) {
numRowsScanned++;
// Using an intermediate unbatched ScanResultValue is not that great memory-wise, but the column list
// needs to be preserved for queries using the compactedList result format
sorter.add(srv);
// Finish scanning the interval containing the limit row
if (numRowsScanned > limit && finalInterval == null) {
long timestampOfLimitRow = srv.getFirstEventTimestamp(scanQuery.getResultFormat());
for (Interval interval : intervalsOrdered) {
if (interval.contains(timestampOfLimitRow)) {
finalInterval = interval;
}
}
if (finalInterval == null) {
throw new ISE("Row came from an unscanned interval");
}
}
}
yielder = yielder.next(null);
doneScanning = yielder.isDone() ||
(finalInterval != null &&
!finalInterval.contains(next.getFirstEventTimestamp(scanQuery.getResultFormat())));
}
final List<ScanResultValue> sortedElements = new ArrayList<>(sorter.size());
Iterators.addAll(sortedElements, sorter.drain());
return Sequences.simple(sortedElements);
}
finally {
yielder.close();
}
}
View on GitHub (pinned to 9b90983fd2)