apache/iceberg · error · UnsupportedOperationException

Row-based reads are not supported

Error message

Row-based reads are not supported

What it means

SparkInputPartitionReaderFactory.createReader is the row-based read entry point for batch scans. The Iceberg Spark columnar reader factory only supports columnar (ColumnarBatch) reads, so calling the row-based entry point is explicitly rejected with UnsupportedOperationException. Iceberg batch reads through this factory must use createColumnarReader instead.

Solutions

  1. Use createColumnarReader(inputPartition) instead of createReader, ensuring supportColumnarReads returned true for the partition
  2. Route row-based reads through a row-oriented reader factory (e.g. the row-based Spark input partition reader factory) rather than the columnar one
  3. If using Spark APIs, make sure the query is planned for columnar execution and the partition tasks are all FileScanTask

Example fix

// before
PartitionReader<InternalRow> reader = factory.createReader(partition);
// after
PartitionReader<ColumnarBatch> reader = factory.createColumnarReader(partition);
Defensive patterns

Strategy: type-guard

Validate before calling

if (partition.allTasksOfType(FileScanTask.class)) {
  factory.createColumnarReader(partition);
}

Type guard

boolean isColumnar = partition.allTasksOfType(FileScanTask.class);

Try / catch

try {
  return factory.createColumnarReader(inputPartition);
} catch (UnsupportedOperationException e) {
  return rowFactory.createReader(inputPartition);
}

Prevention

When it happens

Trigger: Calling createReader(InputPartition) directly on SparkColumnarReaderFactory, or a Spark plan that falls back to row-based batch reads (e.g. a subclass/experimental listener that requests non-columnar reads through this factory).

Common situations: Custom Spark 3.x data source integration code invoking the wrong factory method; tooling or tests assuming row-oriented batch reads from the columnar factory; copying code from SparkBatchQueryScan row-based variants into a columnar context.

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

Appendix: source

Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkColumnarReaderFactory.java:47

import org.apache.spark.sql.vectorized.ColumnarBatch;

class SparkColumnarReaderFactory implements PartitionReaderFactory {
  private final ParquetBatchReadConf parquetConf;
  private final OrcBatchReadConf orcConf;

  SparkColumnarReaderFactory(ParquetBatchReadConf conf) {
    this.parquetConf = conf;
    this.orcConf = null;
  }

  SparkColumnarReaderFactory(OrcBatchReadConf conf) {
    this.orcConf = conf;
    this.parquetConf = null;
  }

  @Override
  public PartitionReader<InternalRow> createReader(InputPartition inputPartition) {
    throw new UnsupportedOperationException("Row-based reads are not supported");
  }

  @Override
  public PartitionReader<ColumnarBatch> createColumnarReader(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 BatchDataReader(partition, parquetConf, orcConf);
    } else {
      throw new UnsupportedOperationException(
          "Unsupported task group for columnar reads: " + partition.taskGroup());
    }
  }

View on GitHub (pinned to 86d9c8fc54)