apache/seatunnel · error · IllegalStateException
checkpointId is already set
Error message
checkpointId is already set
What it means
SchemaChangePhase.setCheckpointId() only allows binding a checkpoint id once; if this.checkpointId is already set (not the -1 sentinel) it throws IllegalStateException. This guards the invariant that a single schema-change phase is associated with exactly one checkpoint barrier.
Source
Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/task/flow/SourceFlowLifeCycle.java:640
public static SchemaChangePhase createBeforePhase() {
return new SchemaChangePhase(PHASE_CHANGE_BEFORE);
}
public static SchemaChangePhase createAfterPhase() {
return new SchemaChangePhase(PHASE_CHANGE_AFTER);
}
public boolean isBeforePhase() {
return PHASE_CHANGE_BEFORE.equals(phase);
}
public boolean isAfterPhase() {
return PHASE_CHANGE_AFTER.equals(phase);
}
public void setCheckpointId(long checkpointId) {
if (this.checkpointId != -1) {
throw new IllegalStateException("checkpointId is already set");
}
this.checkpointId = checkpointId;
}
}
}
View on GitHub (pinned to cf67b549a7)
Solutions
- Ensure a new SchemaChangePhase is created for every schema-change cycle instead of reusing the old one.
- Deduplicate barriers by checkpoint id before calling setCheckpointId.
- If this is reproducible with no duplicate barrier, report/inspect the barrier replay logic in the task execution.
Example fix
// before: reuse phase across checkpoints
phase.setCheckpointId(newId); // throws if already set
// after: recreate phase per cycle
if (phase.getCheckpointId() != -1) {
phase = SchemaChangePhase.createBeforePhase();
}
phase.setCheckpointId(newId); Defensive patterns
Strategy: validation
Validate before calling
if (phase.getCheckpointId() == -1) { phase.setCheckpointId(id); } Type guard
boolean isCheckpointIdUnset(SchemaChangePhase p) { return p.getCheckpointId() == -1; } Try / catch
try { phase.setCheckpointId(id); } catch (IllegalStateException e) { if (e.getMessage().equals("checkpointId is already set")) { /* duplicate barrier; ignore or recreate phase */ } else { throw e; } } Prevention
- Create a fresh SchemaChangePhase per schema-change cycle
- Deduplicate barriers by checkpoint id
- Never reuse phase objects across checkpoint cycles
When it happens
Trigger: setCheckpointId() called a second time on the same SchemaChangePhase instance, e.g. a duplicate barrier trigger or phase object reused across checkpoint cycles without being recreated.
Common situations: Duplicate barrier delivery after task retry; a code path re-triggering triggerBarrier for the same phase; custom engine patches that reuse phase objects.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- schema-change-after checkpoint is already completed, job id:
- schema-change checkpoint[%s,%s] and phase[%s] is not matched
- schema-change checkpoint[%s] is aborted, phase: [%s]
- Column {} already exists in table {}. Skipping change column
- Column {} already exists in table {}. Skipping add column op
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/f9653b7d9ef57761.
Report an issue: GitHub.