{"record":{"id":"dd3a21dc972a1614","repo":"apache/druid","slug":"cannot-find-a-version-for-interval-s","errorCode":null,"errorMessage":"Cannot find a version for interval[%s]","messagePattern":"Cannot find a version for interval\\[(.+?)\\]","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractBatchIndexTask.java","lineNumber":836,"sourceCode":"\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) {\n          final int maxAllowedLockCount = ((ParallelIndexTuningConfig) ingestionSpec.getTuningConfig())\n              .getMaxAllowedLockCount();\n          if (maxAllowedLockCount >= 0 && locks.size() >= maxAllowedLockCount) {\n            throw new MaxAllowedLocksExceededException(maxAllowedLockCount);\n          }\n        }\n        // We don't have a lock for this interval, so we should lock it now.\n        final TaskLock lock = Preconditions.checkNotNull(\n            toolbox.getTaskActionClient().submit(\n                new TimeChunkLockTryAcquireAction(taskLockType, interval)","sourceCodeStart":818,"sourceCodeEnd":854,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractBatchIndexTask.java#L818-L854","documentation":"After determining the interval for a timestamp, findIntervalAndVersion looks up the lock version associated with that interval from the task's listed locks via findVersion. If no lock covers the interval (version is null) in the explicit-intervals path — where locks should already have been acquired at task startup — this ISE is thrown. It means the task is allocating a segment in an interval it never locked.","triggerScenarios":"Explicit-interval ingestion where locks expected at startup were lost (revoked/expired) before segment allocation, so LockListAction returns no version for the record's interval.","commonSituations":"Locks revoked by a competing higher-priority task mid-run; overlord restart dropping lock state; task running far longer than expected while intervals were locked only at startup.","solutions":["Restart/resubmit the task so it re-acquires locks for all explicit intervals at startup.","Check overlord logs for lock revocation and resolve the competing task before rerunning.","Verify no other task is ingesting the same datasource/interval concurrently.","If this recurs, investigate overlord task-storage/lock persistence issues after failovers."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  ingest(records);\n} catch (IllegalStateException e) {\n  if (e.getMessage().startsWith(\"Cannot find a version for interval\")) {\n    // resubmit the task so locks are re-acquired at startup\n  } else throw e;\n}","preventionTips":["Don't let tasks run so long that startup-acquired locks are revoked or expired.","Prevent competing writers on the same datasource/interval.","Monitor overlord restarts/failovers which can drop lock state."],"tags":["indexing-service","locks","segments"],"backgroundTag":"resource-not-found","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}