apache/seatunnel · error · CheckpointStorageException

No checkpoint found for job, job id is: ${jobId}

Error message

No checkpoint found for job, job id is: ${jobId}

What it means

LocalFileStorage.deleteCheckpoint(jobId) throws 'No checkpoint found for job, job id is: <jobId>' when the job's checkpoint directory lists successfully but contains zero checkpoint files. The delete-all API treats an empty directory as an error, so callers deleting all checkpoints of an already-clean job will see this CheckpointStorageException.

Source

Thrown at seatunnel-engine/seatunnel-engine-storage/checkpoint-storage-plugins/checkpoint-storage-local-file/src/main/java/org/apache/seatunnel/engine/checkpoint/storage/localfile/LocalFileStorage.java:371

                        }
                    }
                });
    }

    @Override
    public void deleteCheckpoint(String jobId, String pipelineId, List<String> checkpointIdList)
            throws CheckpointStorageException {
        String parentPath = getStorageParentDirectory() + jobId;
        Collection<File> fileList = new ArrayList<>();
        try {
            fileList = FileUtils.listFiles(new File(parentPath), FILE_EXTENSIONS, false);
        } catch (Exception e) {
            if (!(e.getCause() instanceof NoSuchFileException)) {
                throw new CheckpointStorageException(ExceptionUtils.getMessage(e));
            }
        }
        if (fileList.isEmpty()) {
            throw new CheckpointStorageException(
                    "No checkpoint found for job, job id is: " + jobId);
        }
        fileList.forEach(
                file -> {
                    String fileName = file.getName();
                    String checkpointIdByFileName = getCheckpointIdByFileName(fileName);
                    if (pipelineId.equals(getPipelineIdByFileName(fileName))
                            && checkpointIdList.contains(checkpointIdByFileName)) {
                        try {
                            FileUtils.delete(file);
                        } catch (Exception e) {
                            log.error(
                                    "Failed to delete checkpoint {} for job {}, pipeline {}",
                                    checkpointIdByFileName,
                                    jobId,
                                    pipelineId,
                                    e);
                        }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Check existence first: call getAllCheckpoints(jobId) and skip deleteCheckpoint when the list is empty.
  2. Catch CheckpointStorageException and treat the 'No checkpoint found' message as a benign no-op in cleanup flows.
  3. Verify the jobId matches the job that actually stored checkpoints (check the storage directory listing).
  4. If checkpoints were expected, look for earlier write failures or a misconfigured storage parent directory.

Example fix

// before
storage.deleteCheckpoint(jobId); // throws when job has no checkpoints
// after
if (!storage.getAllCheckpoints(jobId).isEmpty()) {
    storage.deleteCheckpoint(jobId);
} else {
    log.info("No checkpoints to delete for job {}", jobId);
}
Defensive patterns

Strategy: validation

Validate before calling

// Skip delete when the job has no stored checkpoints
if (storage.getAllCheckpoints(jobId).isEmpty()) {
    log.info("No checkpoints stored for job {}, skipping delete", jobId);
    return;
}

Try / catch

try {
    storage.deleteCheckpoint(jobId);
} catch (CheckpointStorageException e) {
    if (e.getMessage().contains("No checkpoint found")) {
        log.info("Job {} checkpoints already removed", jobId);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling deleteCheckpoint(jobId) when no checkpoint files exist for the job — already deleted by a previous call, job never wrote a completed checkpoint, or an external retention process emptied the directory.

Common situations: Retrying job cleanup after a first successful delete; running cleanup for jobs that failed before the first checkpoint snapshot; idempotent cleanup schedulers racing each other; mistakenly using a jobId that has no stored state (wrong id, different storage directory).

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/252b6f298075c339. Report an issue: GitHub.