apache/iceberg · error · IllegalStateException

Unexpected ContentScanTask type: <task.getClass().getName()>

Error message

Unexpected ContentScanTask type: <task.getClass().getName()>

What it means

The reader operator received a ReadCommand whose scan task is of a ContentScanTask subtype it cannot process (neither a data-file task it recognizes nor an EqualityDeleteFileScanTask). This is an internal contract violation between the planner's emitted tasks and the reader's supported types. The operator logs the failure, emits to the error stream, and signals ABORT on READER_ABORT_STREAM.

Source

Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/EqualityConvertReader.java:126

  @Override
  public void processElement(ReadCommand cmd, Context ctx, Collector<IndexCommand> out)
      throws Exception {
    ContentScanTask<?> task = cmd.task();
    ContentFile<?> file = task.file();
    try {
      if (task instanceof FileScanTask dataTask) {
        processDataFile(
            dataTask,
            cmd.mainSnapshotId(),
            cmd.indexGeneration(),
            cmd.dataSequenceNumber(),
            cmd.staging(),
            out);
      } else if (task instanceof EqualityDeleteFileScanTask deleteTask) {
        processDeleteFile(
            deleteTask, cmd.mainSnapshotId(), cmd.indexGeneration(), cmd.dataSequenceNumber(), out);
      } else {
        throw new IllegalStateException(
            "Unexpected ContentScanTask type: " + task.getClass().getName());
      }
    } catch (Exception e) {
      LOG.error("Reader failed to process command for file={}", file.location(), e);
      ctx.output(TaskResultAggregator.ERROR_STREAM, e);
      ctx.output(READER_ABORT_STREAM, DVPosition.ABORT);
    }
  }

  private void processDataFile(
      FileScanTask task,
      Long mainSnapshotId,
      Long indexGeneration,
      long dataSequenceNumber,
      boolean staging,
      Collector<IndexCommand> out)
      throws IOException {
    ContentFile<?> file = task.file();

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Align all Iceberg Flink maintenance classes to a single version - check the deployed jar for duplicates/multiple Iceberg versions on the classpath.
  2. Check the TaskResultAggregator error stream for the offending task class name and trace which operator emitted it.
  3. Ensure the planner only feeds supported tasks (data files and equality delete scan tasks) into the reader stream.
  4. If you added a new task type, extend EqualityConvertReader.processElement to handle it explicitly.

Example fix

// before: reader knows only DataFile/EqualityDelete tasks
// after: add explicit handling or reject early in the planner
if (!(task instanceof DataFileScanTask || task instanceof EqualityDeleteFileScanTask)) {
  throw new IllegalStateException("Planner emitted unsupported task type: " + task.getClass());
}
Defensive patterns

Strategy: type-guard

Validate before calling

// validate before pushing commands into the reader stream
checkState(task instanceof DataFileScanTask || task instanceof EqualityDeleteFileScanTask,
    "Unsupported task type: " + task.getClass());

Type guard

boolean isReaderSupportedTask(ContentScanTask<?> task) {
  return task instanceof DataFileScanTask || task instanceof EqualityDeleteFileScanTask;
}

Try / catch

// reader already aborts via READER_ABORT_STREAM; monitor it
READER_ABORT_STREAM.process((ctx, abort) -> {
  if (abort == DVPosition.ABORT) failJob("reader aborted: unsupported scan task");
});

Prevention

When it happens

Trigger: A planner (or custom code feeding the reader input stream) emits a scan task type outside {DataFileScanTask-like, EqualityDeleteFileScanTask}, e.g. a position-delete scan task or a new task class introduced by an upgrade.

Common situations: Mixed Iceberg connector versions in the job jar; a V2 positional-delete task reaching the reader after misconfiguration; custom operators injecting tasks into the reader stream.

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/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/e1c674bfe3a4d79a. Report an issue: GitHub.