{"record":{"id":"446659b0fa8f420d","repo":"apache/druid","slug":"row-came-from-an-unscanned-interval","errorCode":null,"errorMessage":"Row came from an unscanned interval","messagePattern":"Row came from an unscanned interval","errorType":"exception","errorClass":"IllegalStateException (ISE)","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/query/scan/ScanQueryRunnerFactory.java","lineNumber":259,"sourceCode":"      while (!doneScanning) {\n        ScanResultValue next = yielder.get();\n        List<ScanResultValue> singleEventScanResultValues = next.toSingleEventScanResultValues();\n        for (ScanResultValue srv : singleEventScanResultValues) {\n          numRowsScanned++;\n          // Using an intermediate unbatched ScanResultValue is not that great memory-wise, but the column list\n          // needs to be preserved for queries using the compactedList result format\n          sorter.add(srv);\n\n          // Finish scanning the interval containing the limit row\n          if (numRowsScanned > limit && finalInterval == null) {\n            long timestampOfLimitRow = srv.getFirstEventTimestamp(scanQuery.getResultFormat());\n            for (Interval interval : intervalsOrdered) {\n              if (interval.contains(timestampOfLimitRow)) {\n                finalInterval = interval;\n              }\n            }\n            if (finalInterval == null) {\n              throw new ISE(\"Row came from an unscanned interval\");\n            }\n          }\n        }\n        yielder = yielder.next(null);\n        doneScanning = yielder.isDone() ||\n                       (finalInterval != null &&\n                        !finalInterval.contains(next.getFirstEventTimestamp(scanQuery.getResultFormat())));\n      }\n\n      final List<ScanResultValue> sortedElements = new ArrayList<>(sorter.size());\n      Iterators.addAll(sortedElements, sorter.drain());\n      return Sequences.simple(sortedElements);\n    }\n    finally {\n      yielder.close();\n    }\n  }\n","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/scan/ScanQueryRunnerFactory.java#L241-L277","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (query.getIntervals() != null) {\n  for (Interval iv : query.getQuerySegmentSpec().getIntervals(query)) {\n    // confirm segment min/max time falls within iv\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  results = runner.run(QueryPlus.wrap(query), ctx).toList();\n} catch (IllegalStateException e) {\n  if (e.getMessage().equals(\"Row came from an unscanned interval\")) { /* widen intervals or reindex segments */ }\n  else throw e;\n}","preventionTips":["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."],"tags":["druid","scan-query","interval-mismatch"],"backgroundTag":"internal-invariant-violation","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}