apache/iceberg · error · UnsupportedOperationException

Unsupported task group for row-based reads: +…

Error message

Unsupported task group for row-based reads: + partition.taskGroup()

What it means

SparkRowReaderFactory only supports row-based reads for task groups composed entirely of ChangelogScanTask or PositionDeletesScanTask. When a partition's batch mixes task types (e.g. combined data/deletes tasks), no row reader implementation exists for it and this UnsupportedOperationException is thrown. It indicates the query plan produced a task grouping the row reader cannot handle.

Solutions

  1. Do not use the row reader factory for mixed task groups; use the batch/columnar SparkScan path instead
  2. Check that the read is not accidentally routed through the changelog/deletes-only reader path
  3. If the table mixes delete file types, normalize delete files (e.g. rewrite to position deletes) so tasks group uniformly
  4. File a Spark-Iceberg integration issue if planning itself produced this mixed group

Example fix

// before (custom read path forcing row reads)
PartitionReader<Record> reader = rowReaderFactory.createReader(partition);
// after
PartitionReader<ColumnarBatch> reader = batchReaderFactory.createColumnarReader(partition);
Defensive patterns

Strategy: validation

Validate before calling

if (!(partition instanceof SparkInputPartition)) throw new IllegalArgumentException("unexpected partition type");
SparkInputPartition sp = (SparkInputPartition) partition;
boolean ok = sp.taskGroup().tasks().stream().allMatch(t -> t instanceof ChangelogScanTask || t instanceof PositionDeletesScanTask);
if (!ok) { /* route to batch/columnar reader path instead */ }

Prevention

When it happens

Trigger: Calling SparkRowReaderFactory.createReader with an InputPartition whose task batch is neither all ChangelogScanTask nor all PositionDeletesScanTask (e.g. mixed ScanTask types in one partition).

Common situations: Streaming or incremental reads where the planning layer produces heterogeneous tasks; custom ScanTaskGroup implementations; internal Spark-Iceberg integration mismatches after version upgrades.

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

Appendix: source

Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkRowReaderFactory.java:54

  public PartitionReader<InternalRow> createReader(InputPartition inputPartition) {
    Preconditions.checkArgument(
        inputPartition instanceof SparkInputPartition,
        "Unknown input partition type: %s",
        inputPartition.getClass().getName());

    SparkInputPartition partition = (SparkInputPartition) inputPartition;

    if (partition.allTasksOfType(FileScanTask.class)) {
      return new RowDataReader(partition);

    } else if (partition.allTasksOfType(ChangelogScanTask.class)) {
      return new ChangelogRowReader(partition);

    } else if (partition.allTasksOfType(PositionDeletesScanTask.class)) {
      return new PositionDeletesRowReader(partition);

    } else {
      throw new UnsupportedOperationException(
          "Unsupported task group for row-based reads: " + partition.taskGroup());
    }
  }

  @Override
  public PartitionReader<ColumnarBatch> createColumnarReader(InputPartition inputPartition) {
    throw new UnsupportedOperationException("Columnar reads are not supported");
  }

  @Override
  public boolean supportColumnarReads(InputPartition inputPartition) {
    return false;
  }
}

View on GitHub (pinned to 86d9c8fc54)