apache/druid · error · IllegalArgumentException
Could not find interval for timestamp
Error message
Could not find interval for timestamp [%s]
What it means
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.
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.
Example fix
// before "intervals": ["2024-01-01/2024-01-02"] // data has events on 2024-01-03 // after "intervals": ["2024-01-01/2024-01-04"]
Defensive patterns
Strategy: validation
Validate before calling
DateTime ts = row.getTimestamp();
List<Interval> intervals = granularitySpec.getQuery().getIntervals();
boolean inRange = intervals.stream().anyMatch(i -> i.contains(ts));
if (!inRange) throw new IllegalArgumentException("Timestamp " + ts + " outside configured intervals"); Try / catch
try {
ingest(records);
} catch (IAE e) {
if (e.getMessage().startsWith("Could not find interval for timestamp")) {
// widen intervals or drop the out-of-window record and resume
} else throw e;
} Prevention
- 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.
When it happens
Trigger: Ingesting records whose event timestamp is not contained by any interval listed in granularitySpec.intervals during a batch task with explicit intervals.
Common situations: 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).
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Unspecified interval
- Can't find lock for the interval of segment
- Can't find surrogate task
- Cannot find a version for interval
- Cannot start; not ready!
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/5b5083c6eef39c85.
Report an issue: GitHub.
Appendix: source
Thrown at indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractBatchIndexTask.java:826
final List<TaskLock> locks = toolbox
.getTaskActionClient()
.submit(new LockListAction());
final TaskLock revokedLock = locks.stream().filter(TaskLock::isRevoked).findAny().orElse(null);
if (revokedLock != null) {
throw new ISE("Lock revoked: [%s]", revokedLock);
}
final Map<Interval, String> versions = locks.stream().collect(
Collectors.toMap(TaskLock::getInterval, TaskLock::getVersion)
);
final Interval interval;
final String version;
if (!materializedBucketIntervals.isEmpty()) {
// If granularity spec has explicit intervals, we just need to find the version associated to the interval.
// This is because we should have gotten all required locks up front when the task starts up.
final Optional<Interval> maybeInterval = granularitySpec.bucketInterval(timestamp);
if (!maybeInterval.isPresent()) {
throw new IAE("Could not find interval for timestamp [%s]", timestamp);
}
interval = maybeInterval.get();
if (!materializedBucketIntervals.contains(interval)) {
throw new ISE("Unspecified interval[%s] in granularitySpec[%s]", interval, granularitySpec);
}
version = AbstractBatchIndexTask.findVersion(versions, interval);
if (version == null) {
throw new ISE("Cannot find a version for interval[%s]", interval);
}
} else {
// We don't have explicit intervals. We can use the segment granularity to figure out what
// interval we need, but we might not have already locked it.
interval = granularitySpec.getSegmentGranularity().bucket(timestamp);
final String existingLockVersion = AbstractBatchIndexTask.findVersion(versions, interval);
if (existingLockVersion == null) {
if (ingestionSpec.getTuningConfig() instanceof ParallelIndexTuningConfig) {View on GitHub (pinned to 9b90983fd2)