{"record":{"id":"5b5083c6eef39c85","repo":"apache/druid","slug":"could-not-find-interval-for-timestamp-s","errorCode":null,"errorMessage":"Could not find interval for timestamp [%s]","messagePattern":"Could not find interval for timestamp \\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractBatchIndexTask.java","lineNumber":826,"sourceCode":"    final List<TaskLock> locks = toolbox\n        .getTaskActionClient()\n        .submit(new LockListAction());\n    final TaskLock revokedLock = locks.stream().filter(TaskLock::isRevoked).findAny().orElse(null);\n    if (revokedLock != null) {\n      throw new ISE(\"Lock revoked: [%s]\", revokedLock);\n    }\n    final Map<Interval, String> versions = locks.stream().collect(\n        Collectors.toMap(TaskLock::getInterval, TaskLock::getVersion)\n    );\n\n    final Interval interval;\n    final String version;\n    if (!materializedBucketIntervals.isEmpty()) {\n      // If granularity spec has explicit intervals, we just need to find the version associated to the interval.\n      // This is because we should have gotten all required locks up front when the task starts up.\n      final Optional<Interval> maybeInterval = granularitySpec.bucketInterval(timestamp);\n      if (!maybeInterval.isPresent()) {\n        throw new IAE(\"Could not find interval for timestamp [%s]\", timestamp);\n      }\n\n      interval = maybeInterval.get();\n      if (!materializedBucketIntervals.contains(interval)) {\n        throw new ISE(\"Unspecified interval[%s] in granularitySpec[%s]\", interval, granularitySpec);\n      }\n\n      version = AbstractBatchIndexTask.findVersion(versions, interval);\n      if (version == null) {\n        throw new ISE(\"Cannot find a version for interval[%s]\", interval);\n      }\n    } else {\n      // We don't have explicit intervals. We can use the segment granularity to figure out what\n      // interval we need, but we might not have already locked it.\n      interval = granularitySpec.getSegmentGranularity().bucket(timestamp);\n      final String existingLockVersion = AbstractBatchIndexTask.findVersion(versions, interval);\n      if (existingLockVersion == null) {\n        if (ingestionSpec.getTuningConfig() instanceof ParallelIndexTuningConfig) {","sourceCodeStart":808,"sourceCodeEnd":844,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractBatchIndexTask.java#L808-L844","documentation":"When the granularitySpec has explicit intervals (materializedBucketIntervals non-empty), findIntervalAndVersion uses bucketInterval(timestamp) to find the bucketed interval containing the record's timestamp. If the timestamp falls outside all explicitly configured intervals, no bucket exists and this IAE is thrown. Druid refuses to write data outside the declared ingestion window.","triggerScenarios":"Ingesting records whose event timestamp is not contained by any interval listed in granularitySpec.intervals during a batch task with explicit intervals.","commonSituations":"intervals configured too narrowly while source data contains older/newer events; timezone confusion shifting timestamps outside the range; data drift after the ingestion spec was written; time zone in timestamps misparsed (UTC vs local).","solutions":["Widen granularitySpec.intervals to cover all timestamps present in the input data.","Filter or route out-of-range records before ingestion (e.g. with a transform or pre-filter) so out-of-window rows are dropped explicitly.","Use windowing (drop/fixed/partial) tuning to handle late data instead of failing, where supported.","Check timestamp parsing/timezone config to confirm timestamps are interpreted as intended."],"exampleFix":"// before\n\"intervals\": [\"2024-01-01/2024-01-02\"]  // data has events on 2024-01-03\n// after\n\"intervals\": [\"2024-01-01/2024-01-04\"]","handlingStrategy":"validation","validationCode":"DateTime ts = row.getTimestamp();\nList<Interval> intervals = granularitySpec.getQuery().getIntervals();\nboolean inRange = intervals.stream().anyMatch(i -> i.contains(ts));\nif (!inRange) throw new IllegalArgumentException(\"Timestamp \" + ts + \" outside configured intervals\");","typeGuard":null,"tryCatchPattern":"try {\n  ingest(records);\n} catch (IAE e) {\n  if (e.getMessage().startsWith(\"Could not find interval for timestamp\")) {\n    // widen intervals or drop the out-of-window record and resume\n  } else throw e;\n}","preventionTips":["Profile min/max timestamps of source data before choosing explicit intervals.","Use transforms/windowing to drop or fix out-of-window records instead of failing.","Double-check timestamp parsing timezone configuration."],"tags":["indexing-service","granularity-spec","timestamps"],"backgroundTag":"invalid-argument-value","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"}