apache/iceberg · error · UnsupportedOperationException

Row-based reads are not supported

Error message

Row-based reads are not supported

What it means

SparkColumnarReaderFactory only implements createColumnarReader; the row-based createReader API throws UnsupportedOperationException. Iceberg Spark reads in this path are always columnar (Parquet/ORC vectorized), so requesting a row reader is unsupported by design.

Solutions

  1. Keep vectorized reads enabled so Spark calls createColumnarReader (spark.sql.iceberg.handle-timestamp-without-timezone / vectorization settings consistent).
  2. If a column-incompatible type forces row fallback, either cast/sanitize the schema or disable columnar support reporting for that scan.
  3. Do not call createReader directly; use createColumnarReader with a SparkInputPartition.
  4. Upgrade the connector version if row fallback handling for your schema exists in newer releases.

Example fix

// before
spark.conf.set("spark.sql.sources.useV1SourceList", "") // may push row-path reads
// after
// keep vectorized path: ensure columns are vector-readable, e.g. avoid 'vectorization-enabled'='false' on parquet scans
Defensive patterns

Strategy: validation

Validate before calling

// check the schema is vector-readable before columnar read config
boolean vectorizable = table.schema().columns().stream()
    .allMatch(c -> c.type().typeId() != Type.TypeID.NESTED || supportedNested(c.type()));

Try / catch

try { reader = factory.createReader(partition); } catch (UnsupportedOperationException e) {
  reader = fallbackRowReader(partition);
}

Prevention

When it happens

Trigger: Spark attempts row-based micro-batch reads (createReader) on an Iceberg source partition — happens when vectorized reading is effectively disabled/disallowed by Spark while the data source reports columnar support, or custom reader code invokes createReader directly.

Common situations: spark.sql.execution.useObjectStoreAggregate / vectorized-reader option conflicts; setting read.options('vectorization-enabled'='false') for formats without vector support; schema plans incompatible with columnar batches (complex types) causing Spark to fall back to row reads.

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

Appendix: source

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