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
- Resubmit the supervisor task so all subtask attempts and segment allocations restart consistently
- Inspect the supervisor's task reports and locate the subtask whose reported prevSegmentId no longer matches; kill stale subtasks
- Confirm you are not reusing old subtask spec IDs against a restarted supervisor
- 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
- Always restart the entire supervisor task rather than individual subtasks after failures
- Kill orphaned subtasks from earlier attempts before retrying
- Avoid concurrent tasks (compaction/ingestion) targeting the same intervals without locks
- Track attempt numbers in monitoring to detect stale subtask reports
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
- Could not find interval for timestamp [%s]
- Can't find previous segmentIds for sequence[%s]
- Illegal segmentId format [%s]
- Failed to add a row with timestamp[%s]
- ColumnCapacityExceededException
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/1ef0394d6d5d1b9f.
Report an issue: GitHub.