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

  1. Ensure a new SchemaChangePhase is created for every schema-change cycle instead of reusing the old one.
  2. Deduplicate barriers by checkpoint id before calling setCheckpointId.
  3. 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

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


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