apache/iceberg · error · UnsupportedOperationException
Columnar reads are not supported
Error message
Columnar reads are not supported
What it means
SparkRowReaderFactory explicitly does not support columnar reads: createColumnarReader() always throws UnsupportedOperationException('Columnar reads are not supported'), and supportColumnarReads() returns false. This factory exists solely for row-based reads (changelog/position-deletes).
Source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkRowReaderFactory.java:61
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
- Ensure supportColumnarReads() returns false for scans using this factory so Spark never requests columnar readers
- Do not force columnar batch options on changelog/position-delete scans
- Use the standard SparkTable/SparkBatchQueryScan path which selects the correct reader factory
- If you need columnar reads, use the regular batch scan factory instead of the row reader factory
Example fix
// before
@Override
public boolean supportColumnarReads(InputPartition p) { return true; } // leads to throw
// after
@Override
public boolean supportColumnarReads(InputPartition p) { return false; } Defensive patterns
Strategy: type-guard
Validate before calling
if (factory.supportColumnarReads(partition)) { reader = factory.createColumnarReader(partition); } else { reader = factory.createReader(partition); } Type guard
boolean supportsColumnar = (factory instanceof SparkRowReaderFactory) ? false : factory.supportColumnarReads(partition);
Try / catch
try { return factory.createColumnarReader(p); } catch (UnsupportedOperationException e) { return factory.createReader(p); } Prevention
- Never advertise supportColumnarReads=true for factories that only produce rows
- Don't force columnar batch options on changelog/position-delete scans
- Use the standard batch scan path for columnar reads
When it happens
Trigger: Spark's DataSource V2 batch engine calls createColumnarReader because supportColumnarReads returned true or columnar read options were forced (e.g. spark.sql.sources.v2.batch.scan.enabled with columnar batching, or a custom reader wrapping this factory).
Common situations: Custom scan implementations advertising columnar support but delegating to SparkRowReaderFactory; misconfigured batch read options requesting ColumnarBatch output for changelog/position-delete reads.
Related errors
- Row-based reads are not supported
- Unsupported task group for columnar reads: ${partition.taskG
- Columnar reads are not supported
- Renaming a view is not supported by catalog: ${catalogName}
- Row-based reads are not supported
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/7986212070a4e922.
Report an issue: GitHub.