apache/seatunnel · error · UnsupportedOperationException
The SplitChange type of %s is not supported.
Error message
The SplitChange type of %s is not supported.
What it means
FlussSourceSplitReader only accepts SplitsAddition changes; any other SplitsChange subtype (e.g. SplitsRemoval) is rejected with this UnsupportedOperationException. The reader cannot retract or remove already-subscribed splits.
Source
Thrown at seatunnel-connectors-v2/connector-fluss/src/main/java/org/apache/seatunnel/connectors/seatunnel/fluss/source/FlussSourceSplitReader.java:211
* reports the split in {@code finishedSplits}, yet the base only drops its state one {@code
* pollNext} later (in {@code finishCurrentFetch}), after the split's last record has already
* advanced {@code currentOffset} to the end. A checkpoint landing in that window persists a
* just-completed split, and restoring it hands us back {@code start == end}. Finishing it here
* skips a pointless subscribe + poll and avoids a misleading out-of-range warning should
* retention have meanwhile passed that end.
*
* <p>The {@link LogScanner#EARLIEST_OFFSET} (-2) sentinel of a fresh split floors to 0, so a
* fresh split is only drained when its end offset is 0 — an empty bucket, which the enumerator
* already filters out, leaving that a defensive fallback.
*/
static boolean isDrainedAtAssignment(long startOffset, long endOffset) {
return isBounded(endOffset) && Math.max(startOffset, 0L) >= endOffset;
}
@Override
public void handleSplitsChanges(SplitsChange<FlussSourceSplit> splitsChanges) {
if (!(splitsChanges instanceof SplitsAddition)) {
throw new UnsupportedOperationException(
String.format(
"The SplitChange type of %s is not supported.",
splitsChanges.getClass()));
}
for (FlussSourceSplit split : splitsChanges.splits()) {
long startOffset = split.getStartOffset();
long endOffset = split.getEndOffset();
if (isDrainedAtAssignment(startOffset, endOffset)) {
drainedSplits.add(split.splitId());
log.info(
"Split {} has nothing to read (startOffset={}, endOffset={}); marking finished without subscribing",
split.splitId(),
startOffset,
endOffset);
continue;
}
if (tableScan == null) {
tableScan = createTableScan();View on GitHub (pinned to cf67b549a7)
Solutions
- Ensure only SplitsAddition is sent to this reader (enumerator should not reassign splits of live readers)
- In restore/rebalance paths, recreate the reader instead of sending SplitsRemoval
- Patch handleSplitsChanges to no-op or handle SplitsRemoval if the runtime legitimately sends it
- Upgrade connector/runtime versions so split redistribution matches the push-only model
Example fix
// before (enumerator) enumeratorContext.assignSplit(new SplitsRemoval<>(splits, subtaskId)); // after // do not send removals; splits stay with their reader until task teardown
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(change instanceof SplitsAddition)) {
throw new IllegalArgumentException("Only SplitsAddition is supported by FlussSourceSplitReader");
} Type guard
boolean isAddition(SplitsChange<?> c) { return c instanceof SplitsAddition; } Try / catch
try {
reader.handleSplitsChanges(change);
} catch (UnsupportedOperationException e) {
LOG.warn("Rejected split change {} for Fluss reader", change.getClass(), e);
} Prevention
- Only send SplitsAddition to FlussSourceSplitReader
- Avoid SplitsRemoval in enumerator rebalance logic for this connector
- Test restore/rebalance paths to confirm no removal changes are emitted
When it happens
Trigger: handleSplitsChanges(SplitsChange<FlussSourceSplit>) receives a change instance that is not SplitsAddition — typically SplitsRemoval sent during split reassignment, failover rebalancing, or by custom enumerator logic.
Common situations: A rollback/restore scenario where the framework replays split ownership changes; custom enumerator code issuing SplitsRemoval; older SeaTunnel runtimes emitting removal changes to release 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
- The SplitChange type of %s is not supported.
- Does not support split requests: subtask
- A decoding format must override this method to apply metadat
- Unsupported convert %s to %s
- Unsupported convert ${value.getClass()} to Float, typeDefine
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/826641a24b77171e.
Report an issue: GitHub.