apache/druid · error · IllegalStateException

Can't find previously allocated segmentId[%s] for sequence[%

Error message

Can't find previously allocated segmentId[%s] for sequence[%s]

What it means

Thrown by SinglePhaseParallelIndexTaskRunner.allocateNewSegment when the sequence's list of previously allocated segment IDs exists but does not contain the prevSegmentId reported by the caller. The runner expects each new allocation request to reference a segment ID it previously handed out for that sequence, appended in order. A missing ID means the caller's view of the allocation history is out of sync with the runner's.

Source

Thrown at indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/SinglePhaseParallelIndexTaskRunner.java:236

  ) throws IOException
  {
    NonnullPair<Interval, String> intervalAndVersion = findIntervalAndVersion(timestamp, LockGranularity.TIME_CHUNK);

    MutableObject<SegmentIdWithShardSpec> segmentIdHolder = new MutableObject<>();
    sequenceToSegmentIds.compute(sequenceName, (k, v) -> {
      final int prevSegmentIdIndex;
      final List<String> segmentIds;
      if (prevSegmentId == null) {
        prevSegmentIdIndex = -1;
        segmentIds = v == null ? new ArrayList<>() : v;
      } else {
        segmentIds = v;
        if (segmentIds == null) {
          throw new ISE("Can't find previous segmentIds for sequence[%s]", sequenceName);
        }
        prevSegmentIdIndex = segmentIds.indexOf(prevSegmentId);
        if (prevSegmentIdIndex == -1) {
          throw new ISE("Can't find previously allocated segmentId[%s] for sequence[%s]", prevSegmentId, sequenceName);
        }
      }
      final int nextSegmentIdIndex = prevSegmentIdIndex + 1;
      final SegmentIdWithShardSpec newSegmentId;
      if (nextSegmentIdIndex < segmentIds.size()) {
        SegmentId segmentId = SegmentId.tryParse(dataSource, segmentIds.get(nextSegmentIdIndex));
        if (segmentId == null) {
          throw new ISE("Illegal segmentId format [%s]", segmentIds.get(nextSegmentIdIndex));
        }
        newSegmentId = new SegmentIdWithShardSpec(
            segmentId.getDataSource(),
            segmentId.getInterval(),
            segmentId.getVersion(),
            new BuildingNumberedShardSpec(segmentId.getPartitionNum())
        );
      } else {
        final int partitionNum = Counters.getAndIncrementInt(partitionNumCountersPerInterval, intervalAndVersion.lhs);
        newSegmentId = new SegmentIdWithShardSpec(

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Resubmit the supervisor task so all subtask attempts and segment allocations restart consistently
  2. Inspect the supervisor's task reports and locate the subtask whose reported prevSegmentId no longer matches; kill stale subtasks
  3. Confirm you are not reusing old subtask spec IDs against a restarted supervisor
  4. Check for known fixed bugs in your Druid version and upgrade if affected

Example fix

// before: stale subtask reports prevSegmentId from a prior attempt
runner.allocated(prevSegmentId /* from attempt 1 */, sequenceName);
// after: ensure the subtask is restarted with current attempt state,
// or validate membership before requesting:
if (segmentIds.contains(prevSegmentId)) { runner.allocated(prevSegmentId, sequenceName); }
Defensive patterns

Strategy: retry

Validate before calling

// confirm the reported segment belongs to the current allocation state
List<String> ids = partitionMap.get(sequenceName);
boolean valid = ids != null && ids.contains(prevSegmentId);
if (!valid) { throw new IllegalStateException("stale prevSegmentId " + prevSegmentId); }

Try / catch

catch (ISE e) {
  if (e.getMessage().contains("Can't find previously allocated segmentId")) {
    killStaleSubtasks(supervisorTaskId);
    resubmitSupervisor(taskSpec); // full restart rebuilds allocation history
  } else throw e;
}

Prevention

When it happens

Trigger: A subtask requests the successor segment for prevSegmentId X for sequence S, but S's ID list in the runner's map contains other IDs (e.g., from a different attempt) and not X — typically after task retries with stale allocation state or manually resubmitted subtask specs.

Common situations: Parallel batch ingestion where some subtasks from an earlier attempt survive or are retried after the supervisor rebuilt its partition map; cloning/restoring task state; running overlapping compaction or append tasks on the same interval.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/1ef0394d6d5d1b9f. Report an issue: GitHub.