apache/iceberg · error · UnsupportedOperationException

Row-based reads are not supported

Error message

Row-based reads are not supported

What it means

Capability guard in SparkColumnarReaderFactory.createReader: this factory serves only columnar (ColumnarBatch) reads, so the row-based PartitionReader creation entry point is unsupported and always throws. It fires when Spark requests row-based reading from a columnar-configured reader factory.

Source

Thrown at spark/v4.1/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 createColumnarReader; ensure the read path supports columnar batches
  2. Do not register this factory where row-based reads are required
  3. Use the row-oriented reader factory (SparkBatchQueryScan row reader path) instead

Example fix

// before
readerFactory.createReader(partition);
// after
readerFactory.createColumnarReader(partition);
Defensive patterns

Strategy: fallback

Validate before calling

if (!readerFactory.supportsColumnar) { /* use row path */ }

Try / catch

try { createReader(p); } catch (UnsupportedOperationException e) { reader = createColumnarReader(p); }

Prevention

When it happens

Trigger: Spark requests row-based reads from this reader factory, e.g. a data source option forcing non-columnar reads or Spark internals calling createReader instead of createColumnarReader.

Common situations: Combining this factory with configs like spark.sql.inMemoryColumnarStorage or reader selection logic that expects row-based readers; misuse of the factory outside the normal batch read path.

Related errors


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