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

  1. Use a checkpoint/savepoint created by the exact same SeaTunnel and connector-cdc version
  2. If the state is from an incompatible version, restart the job without restore (fresh run) instead of restoring
  3. Do not share checkpoints between different CDC connector types (e.g. MySQL vs Postgres CDC)
  4. 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

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


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