{"record":{"id":"6e19b0bf976031f3","repo":"apache/iceberg","slug":"failed-to-write-record-s","errorCode":null,"errorMessage":"Failed to write record %s","messagePattern":"Failed to write record (.+?)","errorType":"exception","errorClass":"RuntimeIOException","httpStatus":null,"severity":"error","filePath":"parquet/src/main/java/org/apache/iceberg/parquet/ParquetWriteAdapter.java","lineNumber":56,"sourceCode":" * @deprecated use {@link org.apache.iceberg.parquet.ParquetWriter}\n */\n@Deprecated\npublic class ParquetWriteAdapter<D> implements FileAppender<D> {\n  private ParquetWriter<D> writer;\n  private final MetricsConfig metricsConfig;\n  private ParquetMetadata footer;\n\n  public ParquetWriteAdapter(ParquetWriter<D> writer, MetricsConfig metricsConfig) {\n    this.writer = writer;\n    this.metricsConfig = metricsConfig;\n  }\n\n  @Override\n  public void add(D datum) {\n    try {\n      writer.write(datum);\n    } catch (IOException e) {\n      throw new RuntimeIOException(e, \"Failed to write record %s\", datum);\n    }\n  }\n\n  @Override\n  public Metrics metrics() {\n    Preconditions.checkState(footer != null, \"Cannot produce metrics until closed\");\n    // Note: Metrics reported by this method do not contain a full set of available metrics.\n    // Specifically, it lacks metrics not included in Parquet file's footer (e.g. NaN count)\n    MessageType messageType = footer.getFileMetaData().getSchema();\n    Schema schema = ParquetSchemaUtil.convert(messageType);\n    return ParquetMetrics.metrics(schema, messageType, metricsConfig, footer, Stream.empty());\n  }\n\n  @Override\n  public long length() {\n    return writer.getDataSize();\n  }\n","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/parquet/src/main/java/org/apache/iceberg/parquet/ParquetWriteAdapter.java#L38-L74","documentation":"ParquetWriteAdapter.add(D) writes a record via the underlying ParquetWriter and wraps any IOException in a RuntimeIOException with the message 'Failed to write record <datum>'. It converts checked I/O failures during record writing into runtime exceptions so file-writer pipelines don't declare IOException.","triggerScenarios":"Calling add(datum) when the underlying parquet-mr writer throws IOException — e.g. disk full, underlying output stream closed, encryption failure, or a serialization error surfaced as IOException by parquet-mr.","commonSituations":"Out-of-disk or quota exhaustion on the target filesystem; writing to a closed/aborted task output stream; malformed records that parquet-mr's page writer rejects with an I/O-backed exception.","solutions":["Check filesystem capacity/permissions and the output stream's liveness; then retry the task","Inspect the cause (getCause()) to find the underlying IOException and fix it","Validate that the record matches the write schema before calling add"],"exampleFix":"// before: writing after closing the appender\nappender.close();\nappender.add(record);\n// after: write all records, then close\nappender.add(record);\nappender.close();","handlingStrategy":"try-catch","validationCode":"Preconditions.checkState(!closed, \"Appender already closed\");\n// verify record matches write schema before add\nschema.asStruct().validate(record);","typeGuard":null,"tryCatchPattern":"try {\n  adapter.add(datum);\n} catch (RuntimeIOException e) {\n  LOG.error(\"Record write failed, datum={}, cause={}\", datum, e.getCause());\n  throw e; // task must fail; retry at the commit/task level\n}","preventionTips":["Close appenders only after all records are written","Monitor disk/quota on task output filesystems","Catch RuntimeIOException and surface e.getCause() for diagnosis","Validate records against the schema before writing"],"tags":["parquet","io","write-failure"],"backgroundTag":"file-write-failed","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"}