apache/iceberg · error · UnsupportedOperationException
Received invalid default split request event from subtask
Error message
Received invalid default split request event from subtask %d as Iceberg source uses custom split request event
What it means
AbstractIcebergEnumerator.handleSplitRequest always throws UnsupportedOperationException because the Iceberg FLIP-27 source communicates split requests via a custom SplitRequestEvent that piggybacks finished split ids; the framework's default request path must never be used. Receiving a default split request means a reader subtask sent a non-Iceberg request event to the enumerator.
Solutions
- Use the Iceberg custom SplitRequestEvent (via SourceReaderContext/sendSplitRequest with the Iceberg event class) in any custom reader
- Ensure all reader subtasks run the same Iceberg version as the enumerator
- If using stock IcebergSource readers, check for mixed jars on the classpath (duplicate iceberg-flink versions)
- Do not call the default sendSplitRequest() from readers; rely on the enumerator's assignment logic
Example fix
// before: custom reader using default request
context.sendSplitRequest();
// after: use Iceberg's custom event carrying finished split ids
context.sendSourceEventIfSupported(
new SplitRequestEvent(finishedSplitIds)); Defensive patterns
Strategy: validation
Validate before calling
// readers must never use the default split request path
Preconditions.checkState(
event instanceof SplitRequestEvent,
"Iceberg readers must send SplitRequestEvent, not default requests"); Type guard
if (event instanceof SplitRequestEvent) { /* forward to enumerator */ } Try / catch
// enumerator side: not catchable — design readers to never trigger it // reader side: ensure custom event type is registered with the serializer
Prevention
- Use Iceberg's custom SplitRequestEvent in any custom reader
- Keep iceberg-flink jars at one version on the classpath
- Rely on enumerator auto-assignment instead of default sendSplitRequest()
When it happens
Trigger: A SourceReader (or custom reader) calls context.sendSplitRequest() with the default event instead of the custom Iceberg SplitRequestEvent, or a custom/patched reader version is mixed with the Iceberg enumerator.
Common situations: Custom SourceReader implementations built on IcebergSource reader infrastructure but using vanilla split request APIs, mixed cluster versions during upgrade, or third-party readers targeting the wrong enumerator.
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
- Cannot read data task.
- Altering partition keys is not supported yet.
- Altering partition keys is not supported yet.
- Altering schema is not supported in the old alterTable API…
- Can not alter the default database when the iceberg catalog…
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/d4665d4e13c14eb4.
Report an issue: GitHub.
Appendix: source
Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/source/enumerator/AbstractIcebergEnumerator.java:78
// excessive memory footprint. Some pending splits may not have been discovered yet.
.setUnassignedSplitsGauge(() -> Long.valueOf(assigner.pendingSplitCount()));
this.enumeratorContext.metricGroup().gauge("pendingRecords", assigner::pendingRecords);
}
@Override
public void start() {
assigner.start();
}
@Override
public void close() throws IOException {
assigner.close();
}
@Override
public void handleSplitRequest(int subtaskId, @Nullable String requesterHostname) {
// Iceberg source uses custom split request event to piggyback finished split ids.
throw new UnsupportedOperationException(
String.format(
Locale.ROOT,
"Received invalid default split request event "
+ "from subtask %d as Iceberg source uses custom split request event",
subtaskId));
}
@Override
public void handleSourceEvent(int subtaskId, SourceEvent sourceEvent) {
if (sourceEvent instanceof SplitRequestEvent) {
SplitRequestEvent splitRequestEvent = (SplitRequestEvent) sourceEvent;
LOG.info("Received request split event from subtask {}", subtaskId);
assigner.onCompletedSplits(splitRequestEvent.finishedSplitIds());
readersAwaitingSplit.put(subtaskId, splitRequestEvent.requesterHostname());
assignSplits();
} else {
throw new IllegalArgumentException(
String.format(View on GitHub (pinned to 86d9c8fc54)