{"record":{"id":"6afc798464ca3392","repo":"apache/iceberg","slug":"row-based-reads-are-not-supported","errorCode":null,"errorMessage":"Row-based reads are not supported","messagePattern":"Row-based reads are not supported","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/SparkColumnarReaderFactory.java","lineNumber":47,"sourceCode":"import org.apache.spark.sql.vectorized.ColumnarBatch;\n\nclass SparkColumnarReaderFactory implements PartitionReaderFactory {\n  private final ParquetBatchReadConf parquetConf;\n  private final OrcBatchReadConf orcConf;\n\n  SparkColumnarReaderFactory(ParquetBatchReadConf conf) {\n    this.parquetConf = conf;\n    this.orcConf = null;\n  }\n\n  SparkColumnarReaderFactory(OrcBatchReadConf conf) {\n    this.orcConf = conf;\n    this.parquetConf = null;\n  }\n\n  @Override\n  public PartitionReader<InternalRow> createReader(InputPartition inputPartition) {\n    throw new UnsupportedOperationException(\"Row-based reads are not supported\");\n  }\n\n  @Override\n  public PartitionReader<ColumnarBatch> createColumnarReader(InputPartition inputPartition) {\n    Preconditions.checkArgument(\n        inputPartition instanceof SparkInputPartition,\n        \"Unknown input partition type: %s\",\n        inputPartition.getClass().getName());\n\n    SparkInputPartition partition = (SparkInputPartition) inputPartition;\n\n    if (partition.allTasksOfType(FileScanTask.class)) {\n      return new BatchDataReader(partition, parquetConf, orcConf);\n    } else {\n      throw new UnsupportedOperationException(\n          \"Unsupported task group for columnar reads: \" + partition.taskGroup());\n    }\n  }","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/SparkColumnarReaderFactory.java#L29-L65","documentation":"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.","triggerScenarios":"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).","commonSituations":"Config toggling vectorized reads off for Iceberg scans, or custom Spark code that consumes partitions via PartitionReader<InternalRow> through this factory.","solutions":["Use SparkBatchQueryScan/default reader factory that supports row reads, or keep vectorized reads enabled.","Re-enable vectorized reads (do not set spark.sql.iceberg.vectorized-reader.enabled=false) or let Spark choose supportColumnarReads accordingly.","If row reads are required, read via the TableScan API (Iceberg core) instead of this reader factory."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// ensure vectorized reads stay enabled for this factory\nassert \"true\".equals(spark.conf().get(\"spark.sql.iceberg.vectorized-reader.enabled\", \"true\"));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not disable vectorized reads when using the columnar reader factory","Use the standard Iceberg SparkScanBuilder path so Spark picks the right factory","For row-based needs, use Iceberg's TableScan API instead"],"tags":["spark","columnar","vectorized","unsupported-operation"],"backgroundTag":"operation-not-supported","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}