{"record":{"id":"1acf03bb6e85ed5d","repo":"apache/seatunnel","slug":"checkpoint-is-enabled-and-job-starts-with-savepoin","errorCode":null,"errorMessage":"Checkpoint is enabled and job starts with savepoint, but checkpoint storage is not available","messagePattern":"Checkpoint is enabled and job starts with savepoint, but checkpoint storage is not available","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/master/JobMaster.java","lineNumber":371,"sourceCode":"    }\n\n    private CheckpointStorage resolveCheckpointStorageOrFallback(boolean restart) {\n        if (seaTunnelServer != null && seaTunnelServer.getCheckpointService() != null) {\n            CheckpointStorage storage =\n                    seaTunnelServer.getCheckpointService().getCheckpointStorage();\n            if (storage != null) {\n                return storage;\n            }\n        }\n\n        boolean checkpointEnabled =\n                jobCheckpointConfig != null && jobCheckpointConfig.isCheckpointEnable();\n        boolean startWithSavePoint =\n                jobImmutableInformation != null\n                        && (jobImmutableInformation.isRestoreJob() || restart);\n\n        if (checkpointEnabled && startWithSavePoint) {\n            throw new IllegalStateException(\n                    \"Checkpoint is enabled and job starts with savepoint, but checkpoint storage is not available\");\n        }\n\n        // When checkpoint is disabled, CheckpointManager will not touch the storage. We still need\n        // a non-null placeholder to avoid NPEs during job initialization (especially in local\n        // example runs where SeaTunnelServer components may initialize asynchronously).\n        return new UnsupportedCheckpointStorage();\n    }\n\n    private static final class UnsupportedCheckpointStorage implements CheckpointStorage {\n        private static UnsupportedOperationException unavailable() {\n            return new UnsupportedOperationException(\"Checkpoint storage is unavailable\");\n        }\n\n        @Override\n        public String storeCheckPoint(PipelineState state) {\n            throw unavailable();\n        }","sourceCodeStart":353,"sourceCodeEnd":389,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/master/JobMaster.java#L353-L389","documentation":"JobMaster.resolveCheckpointStorageOrFallback validates checkpoint configuration at job initialization. If checkpointing is enabled AND the job is starting from a savepoint (restore job or restart), but no checkpoint storage (IMap state) is available, the job cannot recover and an IllegalStateException is thrown. Checkpoint storage is essential to read the savepoint state from which the job resumes.","triggerScenarios":"Submitting/restarting a job with checkpoint enabled and a savepoint path (isRestoreJob() true or restart=true) while the checkpoint storage IMap/locally-resolved storage is unavailable - e.g. resuming a job whose checkpoint state was deleted, or running in an environment where the storage was never initialized.","commonSituations":"Restoring a job from a savepoint after the cluster's checkpoint storage was wiped; restarting a job after IMap data loss (cluster restarted without persistence); running local examples where the checkpoint directory/state was manually removed.","solutions":["Restore the checkpoint storage/state (IMap persistence or checkpoint directory) that the savepoint references.","Submit the job without the savepoint (fresh start) if recovery from this savepoint is impossible.","Disable checkpointing for the job if a savepoint start is not actually required.","Verify the checkpoint storage configuration (storage plugin) points to accessible, existing storage."],"exampleFix":"// before: resume with missing savepoint\nsh bin/seatunnel.sh -c job.conf -r <jobId>\n// after: start fresh since savepoint state is gone\nsh bin/seatunnel.sh -c job.conf","handlingStrategy":"validation","validationCode":"// before resuming\nboolean storageExists = checkpointStoragePathExists(savepointPath);\nboolean willStartWithSavepoint = isRestoreJob || restart;\nif (willStartWithSavepoint && !storageExists) {\n    throw new IllegalStateException(\"checkpoint storage missing; cannot resume from savepoint\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    resumeJob(jobId);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"checkpoint storage is not available\")) {\n        submitFreshJob(jobConf); // fall back to a fresh start\n    } else throw e;\n}","preventionTips":["Do not delete checkpoint/IMap persistence directories while jobs may be resumed from them.","Enable cluster IMap persistence if you rely on restart-with-savepoint semantics.","Verify checkpoint storage plugin config points to durable, accessible storage before restoring."],"tags":["checkpoint","savepoint","state","job-restart"],"backgroundTag":"conflicting-config-options","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}