{"record":{"id":"9652442cbd3e6c6a","repo":"apache/druid","slug":"unable-to-fetch-the-version-of-the-segments-in-use","errorCode":null,"errorMessage":"Unable to fetch the version of the segments in use. The lock for the task might have been revoked","messagePattern":"Unable to fetch the version of the segments in use\\. The lock for the task might have been revoked","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/TombstoneHelper.java","lineNumber":168,"sourceCode":"        dataSource,\n        replaceGranularity,\n        maxBuckets\n    );\n\n    final List<TaskLock> locks = taskActionClient.submit(new LockListAction());\n\n    Set<DataSegment> tombstones = new HashSet<>();\n    for (Interval tombstoneInterval : tombstoneIntervals) {\n      String version = null;\n      for (final TaskLock lock : locks) {\n        if (lock.getInterval().contains(tombstoneInterval)) {\n          version = lock.getVersion();\n        }\n      }\n\n      if (version == null) {\n        // Unable to fetch the version number of the segment\n        throw new ISE(\"Unable to fetch the version of the segments in use. The lock for the task might \"\n                      + \"have been revoked\");\n      }\n\n      DataSegment tombstone = createTombstoneForTimeChunkInterval(\n          dataSource,\n          version,\n          new TombstoneShardSpec(),\n          tombstoneInterval\n      );\n      tombstones.add(tombstone);\n    }\n    return tombstones;\n  }\n\n  /**\n   * See the method body for an example and an indepth explanation as to how the replace interval is created\n   *\n   * @param intervalsToDrop    Empty intervals in the query that need to be dropped. They should be aligned with the","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/TombstoneHelper.java#L150-L186","documentation":"TombstoneHelper.computeTombstoneSegmentsForReplace throws this when it cannot obtain a version for an existing segment while computing tombstones for a replace (compact/overwrite) operation. Versions come from segment locks held by the task; a null version means the lock no longer exposes a version — usually because the task's lock was revoked (e.g., superseded by a higher-priority task) while the tombstone computation was running.","triggerScenarios":"During a replace/compaction task, a required time-chunk lock for the target interval was revoked (priority preemption, task kill, or lock expiry) between lock acquisition and version lookup, leaving `version` null.","commonSituations":"Compaction tasks preempted by higher-priority ingestion tasks; long-running replace tasks whose locks expired; manual task termination while tombstone computation is in flight; misconfigured compaction task priority.","solutions":["Retry the compaction/replace task after ensuring no higher-priority task holds conflicting locks","Increase the compaction task's priority (or lower competing ingestion priority) so its locks are not revoked","Shorten the task's runtime or reduce the interval granularity per run so locks are held for a shorter window","Check overlord logs for lock revocation events around the failure time to identify the preempting task"],"exampleFix":"// before: assume lock version is always available\nString version = lock == null ? null : lock.getVersion();\n// after: re-acquire or validate the lock before computing tombstones\nif (version == null) {\n  retryLock(dataSource, interval); // re-acquire before proceeding\n  version = requireNonNull(lock.getVersion());\n}","handlingStrategy":"retry","validationCode":"// verify all required locks are still held before computing tombstones\nfor (TimeChunkLock lock : taskLocks) {\n  if (!lockManager.containsLock(dataSource, groupId, lock.getInterval())) {\n    throw new IllegalStateException(\"lock revoked for \" + lock.getInterval());\n  }\n}","typeGuard":null,"tryCatchPattern":"catch (ISE e) {\n  if (e.getMessage().contains(\"The lock for the task might have been revoked\")) {\n    return retryWithBackoff(() -> recomputeTombstones(dataSource, intervals), 3); // re-acquire locks then retry\n  } throw e;\n}","preventionTips":["Give compaction/replace tasks sufficient priority so locks aren't preempted","Avoid killing long-running tasks mid-flight; cancel at interval boundaries","Monitor overlord lock-revocation events","Keep replace task intervals small enough to complete within lock lifetime"],"tags":["ingestion","tombstone","locks","compaction"],"backgroundTag":"invalid-state-transition","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}