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.createReader can build row readers for mixed/regular tasks, changelog tasks, and all-position-deletes task groups. If the partition's tasks are some other group, it throws UnsupportedOperationException since no row reader exists for that combination.

Solutions

  1. Use columnar reads or the standard batch read path that matches the task group.
  2. Align Spark and Iceberg versions so task types match the factory's supported set.
  3. Inspect the query plan to see which task types are produced and avoid reading them row-based.
  4. Upgrade Iceberg if a newly added task type needs row-reader support.
Defensive patterns

Strategy: validation

Validate before calling

boolean rowReadable = partition.allTasksOfType(PositionDeletesScanTask.class) || partition.allTasksOfType(ChangelogScanTask.class) || /* mixed-regular supported */ true;

Try / catch

try { return factory.createReader(partition); } catch (UnsupportedOperationException e) { return factory.createColumnarReader(partition); /* or fail fast */ }

Prevention

When it happens

Trigger: Row-based (non-columnar) reading of a partition whose ScanTaskGroup contains task types other than the supported ones (e.g. unexpected task group mixing file/deletion task types not handled by the if/else chain).

Common situations: New Iceberg scan task kinds read by an older Spark reader factory; custom scan tasks injected into planning; reading with row-based filters on changelog/position-delete tables with unexpected task compositions.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/561f6b5c6d7eaa79. Report an issue: GitHub.

Appendix: source

Thrown at spark/v4.1/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)