apache/seatunnel · error · IllegalStateException
schema-change checkpoint[%s,%s] and phase[%s] is not matched
Error message
schema-change checkpoint[%s,%s] and phase[%s] is not matched
What it means
In SourceFlowLifeCycle.triggerBarrier(), when a barrier of schema-change type arrives, the engine verifies that the barrier's checkpoint type matches the currently recorded SchemaChangePhase (before-checkpoint pairs with before-phase, after with after). A mismatch means the phase recorded on the source path does not correspond to the barrier the coordinator sent, so an IllegalStateException is thrown.
Source
Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/task/flow/SourceFlowLifeCycle.java:513
}
log.debug(
"trigger barrier [{}] finished, cost: {}ms. taskLocation: [{}]",
barrier.getId(),
System.currentTimeMillis() - startTime,
currentTaskLocation);
CheckpointType checkpointType = ((CheckpointBarrier) barrier).getCheckpointType();
if (checkpointType.isSchemaChangeCheckpoint()) {
if (schemaChanging()) {
if (checkpointType.isSchemaChangeBeforeCheckpoint()
&& schemaChangePhase.get().isBeforePhase()) {
schemaChangePhase.get().setCheckpointId(barrier.getId());
} else if (checkpointType.isSchemaChangeAfterCheckpoint()
&& schemaChangePhase.get().isAfterPhase()) {
schemaChangePhase.get().setCheckpointId(barrier.getId());
} else {
throw new IllegalStateException(
String.format(
"schema-change checkpoint[%s,%s] and phase[%s] is not matched",
barrier.getId(),
checkpointType,
schemaChangePhase.get().getPhase()));
}
log.info(
"lock checkpoint[{}] waiting for complete..., phase: [{}]",
barrier.getId(),
schemaChangePhase.get().getPhase());
} else {
log.debug(
"Ignore schema-change checkpoint[{}] on idle task, phase: [{}]",
barrier.getId(),
checkpointType);
}
}
}View on GitHub (pinned to cf67b549a7)
Solutions
- Restart the affected task so phase state and barrier stream resynchronize.
- Check logs for an earlier failed triggerSchemaChangeBefore/AfterCheckpoint that left the wrong phase set.
- Verify all nodes run the same SeaTunnel version (rolling-upgrade mixing of checkpoint semantics).
- Retry the job from the last consistent checkpoint/snapshot.
Defensive patterns
Strategy: try-catch
Validate before calling
// verify phase matches barrier type before trigger boolean matched = (checkpointType.isSchemaChangeBeforeCheckpoint() && phase.isBeforePhase()) || (checkpointType.isSchemaChangeAfterCheckpoint() && phase.isAfterPhase());
Try / catch
try { triggerBarrier(barrier); } catch (IllegalStateException e) { if (e.getMessage().contains("is not matched")) { restartTaskToResyncPhase(); } else { throw e; } } Prevention
- Keep engine versions uniform across the cluster
- Investigate any earlier schema-change trigger failure immediately
- Restart task from snapshot when phase/barrier mismatch is detected
When it happens
Trigger: triggerBarrier() receives a checkpointType.isSchemaChangeBeforeCheckpoint() barrier while phase is after-phase (or vice versa), or any schema-change-typed barrier while schemaChangePhase is null/mismatched.
Common situations: Checkpoint type/phase bookkeeping desynchronization after a failed or retried schema-change checkpoint; barrier reordering after task restart or recovery from an older checkpoint id; mixed engine/connector versions during rolling upgrade.
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
- schema-change-after checkpoint is already completed, job id:
- schema-change checkpoint[%s] is aborted, phase: [%s]
- checkpointId is already set
- Unsupported alter table event:
- Unsupported alter table event:
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/148a9d1175a4bf40.
Report an issue: GitHub.