apache/iceberg · error · UnsupportedOperationException

Row-based reads are not supported

Error message

Row-based reads are not supported

What it means

SparkColumnarReaderFactory only implements columnar (Vectorized) reads. Spark calls createReader(InputPartition) when the query requests row-based output; since row-based reads are not supported by this factory, it throws UnsupportedOperationException immediately.

Source

Thrown at spark/v3.5/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)

Solutions

  1. Use SparkBatchQueryScan/default reader factory that supports row reads, or keep vectorized reads enabled.
  2. Re-enable vectorized reads (do not set spark.sql.iceberg.vectorized-reader.enabled=false) or let Spark choose supportColumnarReads accordingly.
  3. If row reads are required, read via the TableScan API (Iceberg core) instead of this reader factory.
Defensive patterns

Strategy: validation

Validate before calling

// ensure vectorized reads stay enabled for this factory
assert "true".equals(spark.conf().get("spark.sql.iceberg.vectorized-reader.enabled", "true"));

Prevention

When it happens

Trigger: Spark DataSource V2 planning calling createReader() on a partition when the scan advertises/requests row batches instead of columnar batches (e.g. spark.sql.iceberg.vectorized-reader disabled with this factory in use).

Common situations: Config toggling vectorized reads off for Iceberg scans, or custom Spark code that consumes partitions via PartitionReader<InternalRow> through this factory.

Related errors


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