apache/seatunnel · error · UnsupportedOperationException
Unsupported restored PendingSplitsState: " + checkpointState
Error message
Unsupported restored PendingSplitsState: " + checkpointState
What it means
IncrementalSource.restoreEnumerator reconstructs a split assigner from a restored PendingSplitsState. It supports specific state classes (e.g. HybridPendingSplitsState / IncrementalPhaseState); any other restored state type is rejected with UnsupportedOperationException naming the offending checkpointState object.
Source
Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/base/source/IncrementalSource.java:421
checkpointSnapshotState.getSplitCompletedOffsets());
splitAssigner =
new SnapshotOnlySplitAssigner<>(
assignerContext,
enumeratorContext.currentParallelism(),
checkpointSnapshotState,
dataSourceDialect);
} else if (checkpointState instanceof IncrementalPhaseState) {
SplitAssigner.Context<C> assignerContext =
new SplitAssigner.Context<>(
sourceConfig, capturedTables, new HashMap<>(), new HashMap<>());
splitAssigner =
new IncrementalSplitAssigner<>(
assignerContext,
incrementalParallelism,
offsetFactory,
(IncrementalPhaseState) checkpointState);
} else {
throw new UnsupportedOperationException(
"Unsupported restored PendingSplitsState: " + checkpointState);
}
return new IncrementalSourceEnumerator(enumeratorContext, splitAssigner);
}
private HybridPendingSplitsState restore(
Set<TableId> capturedTables, HybridPendingSplitsState checkpointState) {
SnapshotPhaseState checkpointSnapshotState = checkpointState.getSnapshotPhaseState();
Set<TableId> checkpointCapturedTables =
Stream.concat(
checkpointSnapshotState.getAlreadyProcessedTables().stream(),
checkpointSnapshotState.getRemainingTables().stream())
.collect(Collectors.toSet());
Set<TableId> newTables = Sets.difference(capturedTables, checkpointCapturedTables);
Set<TableId> deletedTables = Sets.difference(checkpointCapturedTables, capturedTables);
checkpointSnapshotState.getRemainingTables().addAll(newTables);
checkpointSnapshotState.getRemainingTables().removeAll(deletedTables);View on GitHub (pinned to cf67b549a7)
Solutions
- Use a checkpoint/savepoint created by the exact same SeaTunnel and connector-cdc version
- If the state is from an incompatible version, restart the job without restore (fresh run) instead of restoring
- Do not share checkpoints between different CDC connector types (e.g. MySQL vs Postgres CDC)
- Check restoredState class in logs to confirm which type was actually saved
Example fix
// before // restore incremental CDC source from a checkpoint saved by connector-cdc version 2.3.4 on engine 2.3.8 bin/seatunnel.sh --config job.conf -r mixed-version-checkpoint // after bin/seatunnel.sh --config job.conf -r matching-version-savepoint // same engine+connector version // or restart fresh bin/seatunnel.sh --config job.conf
Defensive patterns
Strategy: fallback
Validate before calling
// guard restore by checking state type compatibility
if (!(checkpointState instanceof HybridPendingSplitsState) && !(checkpointState instanceof IncrementalPhaseState)) {
throw new IllegalStateException("Incompatible PendingSplitsState for restore: " + checkpointState.getClass());
} Try / catch
try {
enumerator = source.restoreEnumerator(context, checkpointState);
} catch (UnsupportedOperationException e) {
// fall back to a fresh run without restore
} Prevention
- Never restore checkpoints across SeaTunnel/connector version upgrades without a migration plan
- Keep checkpoints per source type — do not reuse across connector types
- Log checkpointState class name in operational tooling before restore
When it happens
Trigger: restoreEnumerator is called with a checkpoint whose PendingSplitsState instance is neither of the supported types — typically a checkpoint produced by a different connector type or an incompatible SeaTunnel/connector-cdc version.
Common situations: Restoring a CDC job's savepoint after an engine or connector upgrade that changed the state class layout, or restoring a state saved by a different source factory (e.g. pure snapshot source) into an incremental source.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Multiple incremental splits are not supported
- The restored committed-offset checkpoint does not contain it
- READ_COMMITTED_OFFSET_FAILED
- Unsupported pending split value type ${value.getClass().getN
- Unsupported pending split list value type ${pendingSplit ==
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/95293c5f5f385fca.
Report an issue: GitHub.