{"record":{"id":"61b9f272415296f9","repo":"apache/iceberg","slug":"failed-to-write-delete-manifests","errorCode":null,"errorMessage":"Failed to write delete manifests","messagePattern":"Failed to write delete manifests","errorType":"exception","errorClass":"RuntimeIOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/SnapshotProducer.java","lineNumber":796,"sourceCode":"    int groupCount = manifestWriterCount(writePoolParallelism, files.size());\n    return ManifestFiles.writeParallel(\n        files, groupCount, writePool(), group -> writeDeleteFileGroup(group, spec));\n  }\n\n  private List<ManifestFile> writeDeleteFileGroup(\n      Collection<DeleteFile> files, PartitionSpec spec) {\n    RollingManifestWriter<DeleteFile> writer = newRollingDeleteManifestWriter(spec);\n\n    try (RollingManifestWriter<DeleteFile> closableWriter = writer) {\n      for (DeleteFile file : files) {\n        if (file.dataSequenceNumber() != null) {\n          closableWriter.add(file, file.dataSequenceNumber());\n        } else {\n          closableWriter.add(file);\n        }\n      }\n    } catch (IOException e) {\n      throw new RuntimeIOException(e, \"Failed to write delete manifests\");\n    }\n\n    return writer.toManifestFiles();\n  }\n\n  /**\n   * Calculates how many manifest writers can be used concurrently to handle the given number of\n   * files without creating too small manifests.\n   *\n   * @param workerPoolSize the size of the available worker pool\n   * @param fileCount the total number of files to be processed\n   * @return the number of manifest writers that can be used concurrently\n   */\n  @VisibleForTesting\n  static int manifestWriterCount(int workerPoolSize, int fileCount) {\n    int limit = IntMath.divide(fileCount, MIN_FILE_GROUP_SIZE, RoundingMode.HALF_UP);\n    return Math.max(1, Math.min(workerPoolSize, limit));\n  }","sourceCodeStart":778,"sourceCodeEnd":814,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/SnapshotProducer.java#L778-L814","documentation":"Analogous to the data-manifest writer, writeDeleteManifests produces manifests listing delete (position/deequality) files for v2+ tables. An IOException during writing is rethrown as RuntimeIOException with this message. The delete-capable snapshot cannot be built without these manifests.","triggerScenarios":"Operations producing delete files (row-level delete via Spark MERGE/DELETE, newDelete, newRewrite with delete files) committing when FileIO cannot write the delete manifest Avro files.","commonSituations":"Object-store outage or throttling during a MERGE INTO job; metadata directory permissions changed; disk full; credential rotation invalidating long-running write sessions; HDFS name-node failover mid-commit.","solutions":["Retry the write/commit after confirming object-store health and credentials.","Verify write permissions on the table metadata location.","Inspect the wrapped IOException cause for the exact storage failure.","If failing intermittently under parallel writes, tune write worker pool size or merge commit batching."],"exampleFix":"// before\nDeleteFile deleteFile = ...;\ntable.newRowDelta().addDeletes(deleteFile).commit(); // fails: RuntimeIOException: Failed to write delete manifests\n// after\n// fix FileIO credentials, then with retry\nTasks.foreach(() -> table.newRowDelta().addDeletes(deleteFile).commit())\n    .retry(3).exponentialBackoff(100, 4);\n","handlingStrategy":"try-catch","validationCode":"// confirm delete support and a writable metadata location before row-delta commits\nValidationException.check(base.formatVersion() >= 2, \"delete files require format v2\");\n// plus a FileIO write probe as in error 651","typeGuard":null,"tryCatchPattern":"try {\n  table.newRowDelta().addDeletes(deleteFile).commit();\n} catch (RuntimeIOException e) {\n  // check cause for storage failure; verify object-store health, then retry\n  throw new RuntimeException(\"commit failed writing delete manifests, check \" + e.getCause(), e);\n}","preventionTips":["Run MERGE/DELETE workloads with retrying commit wrappers.","Watch object-store 5xx/throttling metrics during row-level delete jobs.","Keep metadata and delete-manifest target sizes reasonable to reduce write burst size.","Avoid mid-job credential rotation; use roles scoped to the table location."],"tags":["io","manifest","delete-files","commit","runtime-io-exception"],"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-14T16:17:12.679Z"}