apache/iceberg · error · RuntimeIOException
Failed to write delete manifests
Error message
Failed to write delete manifests
What it means
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.
Source
Thrown at core/src/main/java/org/apache/iceberg/SnapshotProducer.java:796
int groupCount = manifestWriterCount(writePoolParallelism, files.size());
return ManifestFiles.writeParallel(
files, groupCount, writePool(), group -> writeDeleteFileGroup(group, spec));
}
private List<ManifestFile> writeDeleteFileGroup(
Collection<DeleteFile> files, PartitionSpec spec) {
RollingManifestWriter<DeleteFile> writer = newRollingDeleteManifestWriter(spec);
try (RollingManifestWriter<DeleteFile> closableWriter = writer) {
for (DeleteFile file : files) {
if (file.dataSequenceNumber() != null) {
closableWriter.add(file, file.dataSequenceNumber());
} else {
closableWriter.add(file);
}
}
} catch (IOException e) {
throw new RuntimeIOException(e, "Failed to write delete manifests");
}
return writer.toManifestFiles();
}
/**
* Calculates how many manifest writers can be used concurrently to handle the given number of
* files without creating too small manifests.
*
* @param workerPoolSize the size of the available worker pool
* @param fileCount the total number of files to be processed
* @return the number of manifest writers that can be used concurrently
*/
@VisibleForTesting
static int manifestWriterCount(int workerPoolSize, int fileCount) {
int limit = IntMath.divide(fileCount, MIN_FILE_GROUP_SIZE, RoundingMode.HALF_UP);
return Math.max(1, Math.min(workerPoolSize, limit));
}View on GitHub (pinned to 86d9c8fc54)
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.
Example fix
// before
DeleteFile deleteFile = ...;
table.newRowDelta().addDeletes(deleteFile).commit(); // fails: RuntimeIOException: Failed to write delete manifests
// after
// fix FileIO credentials, then with retry
Tasks.foreach(() -> table.newRowDelta().addDeletes(deleteFile).commit())
.retry(3).exponentialBackoff(100, 4);
Defensive patterns
Strategy: try-catch
Validate before calling
// confirm delete support and a writable metadata location before row-delta commits ValidationException.check(base.formatVersion() >= 2, "delete files require format v2"); // plus a FileIO write probe as in error 651
Try / catch
try {
table.newRowDelta().addDeletes(deleteFile).commit();
} catch (RuntimeIOException e) {
// check cause for storage failure; verify object-store health, then retry
throw new RuntimeException("commit failed writing delete manifests, check " + e.getCause(), e);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Failed to write data manifests
- Failed to write manifest list file
- Failed to read manifest: %s
- Failed to read manifest file: %s
- Failed to validate replaced partitions
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/61b9f272415296f9.
Report an issue: GitHub.