apache/iceberg · error · UnsupportedOperationException

Unsupported task group for row-based reads: ${partition.task

Error message

Unsupported task group for row-based reads: ${partition.taskGroup()}

What it means

SparkRowReaderFactory.createReader() builds a row reader based on the composition of scan tasks in the partition: mixed/other task groups beyond ChangelogRowReader and PositionDeletesRowReader cases are rejected. It throws UnsupportedOperationException when the partition's taskGroup() is not a supported group for row-based reads (e.g. a mixture of data files and position deletes that requires a different reader).

Source

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

Solutions

  1. Rewrite the query to avoid the incremental/mixed scan producing the unsupported task group (e.g. scan a single snapshot)
  2. Switch the read to columnar mode, which supports broader task groups
  3. Upgrade Iceberg; newer versions support more task-group combinations in row reads
  4. If issuing incremental scans, ensure start/end snapshots don't span a delete-format change

Example fix

// before
spark.read.format("iceberg").option("scan-task-group", "row")... // mixed tasks fail
// after
spark.read.format("iceberg").load("db.tbl") // default planning picks a supported reader
Defensive patterns

Strategy: type-guard

Validate before calling

boolean rowReadSafe = partition != null && (partition.allTasksOfType(ChangelogScanTask.class) || partition.allTasksOfType(PositionDeletesScanTask.class));

Type guard

boolean isRowReadable(InputPartition p) { return p instanceof SparkInputPartition s && (s.partition().allTasksOfType(PositionDeletesScanTask.class) || isChangelogGroup(s.partition())); }

Try / catch

try { reader = factory.createReader(partition); } catch (UnsupportedOperationException e) { // fall back to default planning/columnar read  }

Prevention

When it happens

Trigger: Reading an Iceberg table in row-based mode where the SparkInputPartition contains a task group that is neither all changelog tasks nor all PositionDeletesScanTask — e.g. mixed data + equality-deletes or combined task types after incremental scans.

Common situations: Incremental scans between snapshots that mix delete kinds; reading tables with v2 equality deletes combined with positional deletes; misconfigured scan type forcing row-based reads over an unsupported task mix.

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/479c1c2460c15753. Report an issue: GitHub.