{"record":{"id":"94750ab729ad4f42","repo":"apache/iceberg","slug":"columnar-reads-are-not-supported","errorCode":null,"errorMessage":"Columnar reads are not supported","messagePattern":"Columnar 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/SparkRowReaderFactory.java","lineNumber":61,"sourceCode":"\n    if (partition.allTasksOfType(FileScanTask.class)) {\n      return new RowDataReader(partition);\n\n    } else if (partition.allTasksOfType(ChangelogScanTask.class)) {\n      return new ChangelogRowReader(partition);\n\n    } else if (partition.allTasksOfType(PositionDeletesScanTask.class)) {\n      return new PositionDeletesRowReader(partition);\n\n    } else {\n      throw new UnsupportedOperationException(\n          \"Unsupported task group for row-based reads: \" + partition.taskGroup());\n    }\n  }\n\n  @Override\n  public PartitionReader<ColumnarBatch> createColumnarReader(InputPartition inputPartition) {\n    throw new UnsupportedOperationException(\"Columnar reads are not supported\");\n  }\n\n  @Override\n  public boolean supportColumnarReads(InputPartition inputPartition) {\n    return false;\n  }\n}\n","sourceCodeStart":43,"sourceCodeEnd":69,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/SparkRowReaderFactory.java#L43-L69","documentation":"This reader factory is used only for row-based reads (position deletes, changelogs); columnar batch reads are intentionally not implemented. createColumnarReader() unconditionally throws UnsupportedOperationException, and supportColumnarReads() reports false so Spark should never batch-read through it.","triggerScenarios":"Spark requests a columnar reader (PartitionReader<ColumnarBatch>) from this factory — normally only possible if Spark ignores supportColumnarReads()==false or a custom reader is registered for the wrong scan type.","commonSituations":"Custom Spark integrations or spark.sql.sources.useV1Reader-style misconfiguration forcing columnar reads on a position-deletes/changelog scan.","solutions":["Do not request columnar reads for these scans; use row-based reads (supportColumnarReads is false by design).","Remove overrides that force columnar batch reading for Iceberg row-reader scans.","If columnar reads are needed, use a different scan/source that supports batches instead of SparkRowReaderFactory."],"exampleFix":"// before\nspark.conf.set(\"spark.sql.sources.useV1Reader\", \"v1\") // forces columnar path assumptions\n\n// after\n// use the default reader path; batch reads are unsupported for these scans","handlingStrategy":"type-guard","validationCode":"if (!readerFactory.supportColumnarReads(inputPartition)) {\n  reader = readerFactory.createReader(inputPartition);\n} else {\n  reader = readerFactory.createColumnarReader(inputPartition);\n}","typeGuard":"boolean supportsBatches = readerFactory.supportColumnarReads(partition); // always false here\nassert !supportsBatches : \"columnar reads unsupported for this factory\";","tryCatchPattern":"try {\n  reader = readerFactory.createColumnarReader(partition);\n} catch (UnsupportedOperationException e) {\n  reader = readerFactory.createReader(partition); // row-based fallback\n}","preventionTips":["Always honor supportColumnarReads()==false.","Don't force columnar reader configs for these scans.","Use the appropriate Iceberg source for batch/columnar workloads."],"tags":["spark","columnar-reads","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-23T08:17:48.524Z"}