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

  1. Verify the checkpoint request's sequence number and offsets match a currently active sequence in the task group
  2. Re-issue the checkpoint only for sequences the task has actually reported (check task reports / logs)
  3. 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

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


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)