apache/druid · error · IllegalStateException
No such previous checkpoint
Error message
No such previous checkpoint [%s] found
What it means
When a checkpoint request arrives, the supervisor walks the task group's stored checkpoint history (a map keyed by descending index) to find an entry matching the requested checkpoint metadata. If it walks all the way to index 0 without a match, the requested checkpoint does not correspond to any previously recorded checkpoint, and an ISE is thrown.
Solutions
- Verify the checkpoint request's sequence number and offsets match a currently active sequence in the task group
- Re-issue the checkpoint only for sequences the task has actually reported (check task reports / logs)
- If supervisor state was lost, restart tasks so checkpoints are rebuilt from the beginning of the sequence
Example fix
null
Defensive patterns
Strategy: try-catch
Validate before calling
// Before requesting a checkpoint, confirm the sequence is active in the group:
boolean isActive = supervisor.checkpointIsActive(taskGroupId, checkpointMetadata.getSequenceNumber());
if (!isActive) { /* don't POST the checkpoint */ } Try / catch
try {
supervisor.checkpoint(taskGroupId, checkpointMetadata);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("No such previous checkpoint")) {
log.warn("Checkpoint for stale/unknown sequence ignored: %s", checkpointMetadata);
} else throw e;
} Prevention
- Only checkpoint sequences currently reported by the task
- Avoid re-sending old checkpoint requests after supervisor restarts
- Check task reports for the current sequence before building checkpoint payloads
When it happens
Trigger: Calling the supervisor's checkpoint REST endpoint (createCheckpointFromTaskStopMetadataCheckpoints / checkpoint handling) with a CheckpointDataSourceMetadata whose sequence number/offsets do not match any entry in the task group's sortedCheckpoints history, or when the checkpoint history is empty.
Common situations: Checkpointing a task whose replicas already diverged; sending checkpoints for an old sequence after the supervisor has pruned history; double-checkpointing or restarting supervisor which lost in-memory checkpoint state; wrong sequence number in the checkpoint request body.
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
- Killing task[ ] as it failed to return start time.
- Cannot find taskGroup
- Could not fetch partitions for topic/stream
- Driver for sequence[ ] attempted to publish invalid…
- Exclusive start partitions
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/c17c762c6a3f677f.
Report an issue: GitHub.
Appendix: source
Thrown at indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisor.java:955
if (isValidTaskGroup(taskGroupId, taskGroup)) {
final TreeMap<Integer, Map<PartitionIdType, SequenceOffsetType>> checkpoints = taskGroup.checkpointSequences;
// check validity of previousCheckpoint
int index = checkpoints.size();
for (int sequenceId : checkpoints.descendingKeySet()) {
Map<PartitionIdType, SequenceOffsetType> checkpoint = checkpoints.get(sequenceId);
// We have already verified the stream of the current checkpoint is same with that in ioConfig.
// See checkpoint().
if (checkpoint.equals(checkpointMetadata.getSeekableStreamSequenceNumbers()
.getPartitionSequenceNumberMap()
)) {
break;
}
index--;
}
if (index == 0) {
throw new ISE("No such previous checkpoint [%s] found", checkpointMetadata);
} else if (index < checkpoints.size()) {
// if the found checkpoint is not the latest one then already checkpointed by a replica
Preconditions.checkState(index == checkpoints.size() - 1, "checkpoint consistency failure");
log.info("Already checkpointed with sequences [%s]", checkpoints.lastEntry().getValue());
return;
}
final Map<PartitionIdType, SequenceOffsetType> newCheckpoint = checkpointTaskGroup(taskGroup, false).get();
if (MapUtils.isNotEmpty(newCheckpoint)) {
taskGroup.addNewCheckpoint(newCheckpoint);
log.info("Handled checkpoint notice, new checkpoint is [%s] for taskGroup [%s]", newCheckpoint, taskGroupId);
} else {
log.warn("New checkpoint is null for taskGroup [%s]", taskGroupId);
}
}
}
boolean isValidTaskGroup(int taskGroupId, @Nullable TaskGroup taskGroup)
{View on GitHub (pinned to 9b90983fd2)