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

  1. Use the Iceberg custom SplitRequestEvent (via SourceReaderContext/sendSplitRequest with the Iceberg event class) in any custom reader
  2. Ensure all reader subtasks run the same Iceberg version as the enumerator
  3. If using stock IcebergSource readers, check for mixed jars on the classpath (duplicate iceberg-flink versions)
  4. 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

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


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)