apache/seatunnel · error · JobException
The job id %s has already been submitted and is not starting
Error message
The job id %s has already been submitted and is not starting with a savepoint.
What it means
On submission with an explicit jobId, the engine checks job history metrics to detect duplicate submissions. If non-empty metrics already exist for that jobId (a job with that id was previously submitted) and the request is not a savepoint/restore start, submission fails with this JobException. It prevents silently reusing a job id that already has history.
Source
Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/CoordinatorService.java:1443
jobMaster =
new JobMaster(
jobId,
jobImmutableInformation,
this.nodeEngine,
mdcExecutorService,
getResourceManager(),
getJobHistoryService(),
runningJobStateIMap,
runningJobStateTimestampsIMap,
ownedSlotProfilesIMap,
runningJobInfoIMap,
engineConfig,
seaTunnelServer);
if (!isStartWithSavePoint
&& getJobHistoryService().getJobMetrics(jobId)
!= JobMetrics.empty()) {
throw new JobException(
String.format(
"The job id %s has already been submitted and is not starting with a savepoint.",
jobId));
}
long initializationTimestamp = System.currentTimeMillis();
submittedJobInfo =
new JobInfo(initializationTimestamp, jobImmutableInformation);
runningJobInfoIMap.put(jobId, submittedJobInfo);
jobMaster.init(initializationTimestamp, false);
// Initialize the JobMaster and add it to the pendingJobQueue, ensuring that
// calling the getJobMaster method does not return NULL when the
// jobSubmitFuture is still running.
PendingJobInfo pendingJobInfo =
new PendingJobInfo(PendingSourceState.SUBMIT, jobMaster);
pendingJobQueue.put(pendingJobInfo);
// We specify that when init is complete, the submitJob is complete.
jobSubmitFuture.complete(null);
} catch (Throwable e) {View on GitHub (pinned to cf67b549a7)
Solutions
- Do not set a fixed jobId; let the engine generate a new unique id per submission.
- Use start-with-savepoint if you intentionally want to resume a job under the same id.
- Check job history (getJobMetrics / REST jobinfo) before submitting with a custom id.
- Centralize job id generation (e.g. new Random().nextLong()) in submission tooling.
Example fix
// before long jobId = 861912345L; // id copied from an old config client.submitJob(jobId, config, false); // after long jobId = new Random().nextLong(); client.submitJob(jobId, config, false);
Defensive patterns
Strategy: validation
Validate before calling
// ensure the id is unused before a non-savepoint submission
JobMetrics existing = jobClient.getJobMetrics(jobId);
if (existing != null && !existing.equals(JobMetrics.empty())) {
jobId = new Random().nextLong();
} Try / catch
try {
client.submitJob(jobId, config, false);
} catch (JobException e) {
if (e.getMessage().contains("has already been submitted")) {
client.submitJob(new Random().nextLong(), config, false);
} else { throw e; }
} Prevention
- Never hardcode jobId in shared job configs or scripts.
- Strip old jobId values when replaying historical job configs.
- Centralize job id generation in submission tooling.
- Use savepoint start when intentionally resuming under an existing id.
When it happens
Trigger: submitJob called with a jobId whose job history metrics are non-empty, with isStartWithSavePoint=false.
Common situations: Hardcoded jobId in a shared config or script executed twice; replaying an old job config that still contains its original jobId; CI pipelines resubmitting without id generation.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- restoreSourceJobId is required when restoreMode=%s
- restoreSourceJobId must reference a historical terminal sour
- The job id %s is waiting for terminal state cleanup, please
- Unsupported checkpoint history status %s
- ${CONNECTOR_JAR_HA_STORAGE_TYPE} must in [localfile, hdfs]
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/0d67e6bc00f5aec7.
Report an issue: GitHub.