apache/seatunnel · critical · IOException

Cannot fetch from another split - no split remaining.

Error message

Cannot fetch from another split - no split remaining.

What it means

checkSplitOrStartNext() pops the next split from the queued splits when it can assign a new one; the queue returned null/empty despite canAssignNextSplit() being true, which is an impossible/invalid internal state (no split remaining to fetch from). Thrown as IOException to fail the reader task.

Solutions

  1. Restart the job from the last successful checkpoint to resynchronize split state
  2. Enable debug logging of handleSplitsChanges/checkSplitOrStartNext to confirm splits were actually sent to this reader
  3. Verify the enumerator is alive and assigning splits (check for table-discovery or assignment errors upstream)
  4. Upgrade SeaTunnel/connector version if this matches a known split-assignment race bug
Defensive patterns

Strategy: try-catch

Validate before calling

// Before fetch: confirm a split is queued or a split is active
if (canAssignNextSplit() && splits.isEmpty() && currentSplitId == null) {
    LOG.warn("No split available; skipping fetch cycle instead of polling null");
    return;
}

Try / catch

try { checkSplitOrStartNext(); }
catch (IOException e) {
  if (e.getMessage().contains("no split remaining")) { restartFromLastCheckpoint(); }
  else { throw e; }
}

Prevention

When it happens

Trigger: fetch() -> checkSplitOrStartNext(): canAssignNextSplit() returns true (e.g. currentSplitId is null and no finished-split is pending) but splits.poll() yields null — meaning the reader believes it should take a new split while none was delivered.

Common situations: Enumerator and reader state divergence after checkpoint restore; splits consumed but reader state (emittedFinishedSplitId/currentSplitId) not updated consistently; engine bug in split delivery order.

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/7c71935926c6e475. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/base/source/reader/IncrementalSourceSplitReader.java:161

            currentSplitId = null;
            emittedFinishedSplitId = null;
        }
    }

    private void checkNeedStopBinlogReader() {
        // TODO Currently not supported
    }

    protected void checkSplitOrStartNext() throws IOException {
        // the stream fetcher should keep alive
        if (currentFetcher instanceof IncrementalSourceStreamFetcher) {
            return;
        }

        if (canAssignNextSplit()) {
            final SourceSplitBase nextSplit = splits.poll();
            if (nextSplit == null) {
                throw new IOException("Cannot fetch from another split - no split remaining.");
            }
            currentSplitId = nextSplit.splitId();
            emittedFinishedSplitId = null;

            if (nextSplit.isSnapshotSplit()) {
                if (currentFetcher == null) {
                    final FetchTask.Context taskContext =
                            dataSourceDialect.createFetchTaskContext(nextSplit, sourceConfig);
                    currentFetcher = new IncrementalSourceScanFetcher(taskContext, subtaskId);
                }
            } else {
                // point from snapshot split to incremental split
                if (currentFetcher != null) {
                    log.info(
                            "It's turn to read incremental split, close current snapshot fetcher.");
                    currentFetcher.close();
                }
                final FetchTask.Context taskContext =

View on GitHub (pinned to cf67b549a7)