apache/seatunnel · error · UnsupportedOperationException

Multiple incremental splits are not supported

Error message

Multiple incremental splits are not supported

What it means

When restoring a CDC source from checkpoint, BaseChangeStreamTableSourceFactory.getRestoreTableStruct collects restored splits and filters for incremental splits. Incremental (streaming) phase must have at most one incremental split; more than one indicates corrupted or duplicated checkpoint state, so UnsupportedOperationException is thrown.

Source

Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/base/source/BaseChangeStreamTableSourceFactory.java:80

    }

    public abstract <T, SplitT extends SourceSplit, StateT extends Serializable>
            TableSource<T, SplitT, StateT> restoreSource(
                    TableSourceFactoryContext context, List<CatalogTable> restoreTableStruct);

    protected <SplitT extends SourceSplit, StateT extends Serializable>
            List<CatalogTable> getRestoreTableStruct(
                    ChangeStreamTableSourceState<StateT, SplitT> state) {
        List<IncrementalSplit> incrementalSplits =
                state.getSplits().stream()
                        .flatMap(List::stream)
                        .filter(e -> e != null)
                        .map(e -> SourceSplitBase.class.cast(e))
                        .filter(e -> e.isIncrementalSplit())
                        .map(e -> e.asIncrementalSplit())
                        .collect(Collectors.toList());
        if (incrementalSplits.size() > 1) {
            throw new UnsupportedOperationException(
                    "Multiple incremental splits are not supported");
        }

        if (incrementalSplits.size() == 1) {
            IncrementalSplit incrementalSplit = incrementalSplits.get(0);
            if (incrementalSplit.getCheckpointTables() != null) {
                List<CatalogTable> checkpointTableStruct = incrementalSplit.getCheckpointTables();
                log.info("Restore source using checkpoint tables: {}", checkpointTableStruct);
                return checkpointTableStruct;
            }
            if (incrementalSplit.getCheckpointDataType() != null) {
                // TODO: Waiting for remove of compatible logic
                List<CatalogTable> checkpointDataTypeStruct =
                        CatalogTableUtil.convertDataTypeToCatalogTables(
                                incrementalSplit.getCheckpointDataType(), "default.default");
                log.info("Restore source using checkpoint tables: {}", checkpointDataTypeStruct);
                return checkpointDataTypeStruct;
            }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Delete the failed checkpoint state and restart the job from scratch (or from a consistent snapshot savepoint)
  2. Ensure the same SeaTunnel and connector-cdc versions are used to save and restore the checkpoint
  3. Do not manually merge or duplicate checkpoint split files; restore from an untouched savepoint
  4. If developing a custom CDC connector, ensure only one incremental split is ever produced per source

Example fix

// before
// restore with checkpoint from older incompatible connector version -> multiple incremental splits
bin/seatunnel.sh --config job.conf -r old-checkpoint-id
// after
// upgrade both nodes, then restore from a savepoint created with the same version
bin/seatunnel.sh --config job.conf -r consistent-savepoint-id
Defensive patterns

Strategy: fallback

Validate before calling

// before restoring, verify only one incremental split exists in state
long n = restoredSplits.stream().filter(SourceSplitBase::isIncrementalSplit).count();
if (n > 1) throw new IllegalStateException("Corrupt checkpoint: " + n + " incremental splits");

Try / catch

try {
    factory.restoreSource(...);
} catch (UnsupportedOperationException e) {
    // fall back to a fresh (non-restored) submission
}

Prevention

When it happens

Trigger: Calling restoreSource (which calls getRestoreTableStruct) with a restored SourceSplitBase collection where more than one split reports isIncrementalSplit() == true.

Common situations: Restoring a checkpoint/savepoint written by a different SeaTunnel or connector version with an incompatible split layout, manually edited/copied checkpoint data, or a custom connector that incorrectly emits multiple incremental splits.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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