{"record":{"id":"44f839980f845a07","repo":"apache/iceberg","slug":"batch-reading-is-not-supported-in-avro-reader","errorCode":null,"errorMessage":"Batch reading is not supported in Avro reader","messagePattern":"Batch reading is not supported in Avro reader","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/avro/AvroFormatModel.java","lineNumber":252,"sourceCode":"      // This is not an error since filtering is best-effort.\n      return this;\n    }\n\n    @Override\n    public ReadBuilder<D, S> set(String key, String value) {\n      // Configuration is not used for Avro reader creation\n      return this;\n    }\n\n    @Override\n    public ReadBuilder<D, S> reuseContainers() {\n      internal.reuseContainers();\n      return this;\n    }\n\n    @Override\n    public ReadBuilder<D, S> recordsPerBatch(int numRowsPerBatch) {\n      throw new UnsupportedOperationException(\"Batch reading is not supported in Avro reader\");\n    }\n\n    @Override\n    public ReadBuilder<D, S> idToConstant(Map<Integer, ?> newIdToConstant) {\n      this.idToConstant = newIdToConstant;\n      return this;\n    }\n\n    @Override\n    public ReadBuilder<D, S> withNameMapping(org.apache.iceberg.mapping.NameMapping nameMapping) {\n      internal.withNameMapping(nameMapping);\n      return this;\n    }\n\n    @Override\n    public CloseableIterable<D> build() {\n      // The file schema is passed directly to the DatumReader by the Avro read path, so null is\n      // passed here","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/avro/AvroFormatModel.java#L234-L270","documentation":"The Avro format model's ReadBuilder.recordsPerBatch is unsupported because the Avro reader returns an iterator of individual records rather than columnar batches. Calling it always throws UnsupportedOperationException. Batch-oriented reads (e.g. Arrow/Vectorized readers) are only available for columnar formats like Parquet.","triggerScenarios":"Calling readBuilder(...).recordsPerBatch(n).build() on an Avro file/table scan, typically in vectorized-read code paths that assume a batch-capable format model.","commonSituations":"Generic batch-read code shared across Parquet/Avro/ORC writers applied to Avro; engine integrations requesting batches for all formats; configuration that enables vectorized/batch reading without checking the file format.","solutions":["Use the record-at-a-time read path for Avro (omit recordsPerBatch and iterate the returned iterator)","Configure the read path to disable batching/vectorization for Avro files","Use Parquet when batched reads are required","Branch on format model capability before calling recordsPerBatch"],"exampleFix":"// before\nCloseableIterator<ColumnBatch<T>> it =\n    readBuilder(io, file).recordsPerBatch(1024).build(); // avro: throws\n\n// after\nCloseableIterator<T> it = readBuilder(io, file).build(); // record iterator","handlingStrategy":"validation","validationCode":"if (\"avro\".equals(fileFormat) && batchSize > 0) { throw new IllegalArgumentException(\"Batching unsupported for Avro reads\"); }","typeGuard":"boolean supportsBatchRead(FormatModel m) { return !(m instanceof AvroFormatModel); }","tryCatchPattern":"try { builder.recordsPerBatch(n).build(); } catch (UnsupportedOperationException e) { /* fall back to record-at-a-time iterator */ }","preventionTips":["Gate vectorized/batch config on file format","Use plain iterators for Avro scans","Prefer Parquet where batched reads matter"],"tags":["avro","batch-read","unsupported","vectorization"],"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"}