apache/iceberg · warning
Failed to get deleted files: this may cause orphaned data fi
Error message
Failed to get deleted files: this may cause orphaned data files
What it means
During incremental cleanup, findFilesToDelete scans manifests with DELETE entries in parallel to compute deleted data files. If scanning a manifest fails (after 3 retries), this WARN 'Failed to get deleted files: this may cause orphaned data files' is logged. Because the failed manifest's DELETE entries are unknown, files that should be expired may be left as orphans.
Source
Thrown at core/src/main/java/org/apache/iceberg/IncrementalFileCleanup.java:294
expiredStatisticsFilesLocations(beforeExpiration, afterExpiration);
LOG.debug("Deleting {} statistics files", expiredStatisticsFilesLocations.size());
deleteFiles(expiredStatisticsFilesLocations, "statistics files");
}
}
private Set<String> findFilesToDelete(
Set<ManifestFile> manifestsToScan,
Set<ManifestFile> manifestsToRevert,
Set<Long> validIds,
Map<Integer, PartitionSpec> specsById) {
Set<String> filesToDelete = ConcurrentHashMap.newKeySet();
Tasks.foreach(manifestsToScan)
.retry(3)
.suppressFailureWhenFinished()
.executeWith(planExecutorService)
.onFailure(
(item, exc) ->
LOG.warn("Failed to get deleted files: this may cause orphaned data files", exc))
.run(
manifest -> {
// the manifest has deletes, scan it to find files to delete
try (ManifestReader<?> reader = ManifestFiles.open(manifest, fileIO, specsById)) {
for (ManifestEntry<?> entry : reader.entries()) {
// if the snapshot ID of the DELETE entry is no longer valid, the data can be
// deleted
if (entry.status() == ManifestEntry.Status.DELETED
&& !validIds.contains(entry.snapshotId())) {
// use toString to ensure the path will not change (Utf8 is reused)
filesToDelete.add(entry.file().location());
}
}
} catch (IOException e) {
throw new RuntimeIOException(e, "Failed to read manifest file: %s", manifest);
}
});
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Check the WARN cause and verify the manifest file exists and is readable via the FileIO.
- Do not run concurrent expirations; rerun expiration later so missed manifests are scanned then.
- Plan a full (non-incremental) cleanup or an orphan-file removal to catch files skipped by this run.
- Increase retry robustness (check network/config) if throttling is the cause.
Defensive patterns
Strategy: retry
Validate before calling
// verify manifests referenced by snapshots are readable before cleanup ValidationHelpers.checkManifestsReadable(table, io); // custom check opening each manifest
Try / catch
try {
table.expireSnapshots().execute();
} catch (RuntimeException e) {
LOG.warn("Some manifests could not be scanned; orphan sweep recommended", e);
} Prevention
- Schedule periodic remove-orphan-files to reclaim files skipped by failed manifest scans.
- Avoid overlapping maintenance tasks deleting manifests mid-run.
- Monitor for corrupted manifests after failed writes and repair via table recovery.
- Confirm read permissions on all manifest paths.
When it happens
Trigger: filesToDelete -> findFilesToDelete opens a ManifestReader (ManifestFiles.open) for each manifest to scan and iterates entries; a manifest object is unreadable/corrupted, or the IO throws transiently, for manifests flagged as having deletes.
Common situations: Manifests deleted or unreadable due to eventual consistency after concurrent expiration; corrupt manifests from a failed write; missing object-store read permissions; throttling under parallel planning.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Failed to get added files: this may cause orphaned data file
- Failed on snapshot {} while reading manifest list: {}
- Failed to close manifest list: %s
- Failed to read manifest file: %s
- An error occurred while aborting the stream
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/2afa43d4bb02ed34.
Report an issue: GitHub.