{"record":{"id":"bf6712c9f28762ca","repo":"apache/iceberg","slug":"failed-to-close","errorCode":null,"errorMessage":"Failed to close","messagePattern":"Failed to close","errorType":"exception","errorClass":"RuntimeIOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/DeleteFileIndex.java","lineNumber":516,"sourceCode":"          .throwFailureWhenFinished()\n          .executeWith(executorService)\n          .run(\n              deleteFile -> {\n                try (CloseableIterable<ManifestEntry<DeleteFile>> reader = deleteFile) {\n                  for (ManifestEntry<DeleteFile> entry : reader) {\n                    if (entry.dataSequenceNumber() > minSequenceNumber) {\n                      DeleteFile file = entry.file();\n                      // keep minimum stats to avoid memory pressure\n                      Set<Integer> columns =\n                          file.content() == FileContent.POSITION_DELETES\n                              ? Set.of(MetadataColumns.DELETE_FILE_PATH.fieldId())\n                              : Set.copyOf(file.equalityFieldIds());\n                      // copy with stats for better filtering against data file stats\n                      files.add(ContentFileUtil.copy(file, true, columns));\n                    }\n                  }\n                } catch (IOException e) {\n                  throw new RuntimeIOException(e, \"Failed to close\");\n                }\n              });\n      return files;\n    }\n\n    private Collection<Schema> schemas() {\n      if (schemasById != null) {\n        return schemasById.values();\n      } else {\n        return specsById.values().stream().map(PartitionSpec::schema).collect(Collectors.toList());\n      }\n    }\n\n    DeleteFileIndex build() {\n      Map<Integer, Types.NestedField> fieldsById = Schema.indexFields(schemas());\n      Function<Integer, Types.NestedField> fieldLookup = fieldsById::get;\n      Iterable<DeleteFile> files = deleteFiles != null ? filterDeleteFiles() : loadDeleteFiles();\n","sourceCodeStart":498,"sourceCodeEnd":534,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/DeleteFileIndex.java#L498-L534","documentation":"DeleteFileIndex.loadDeleteFiles reads manifest entries inside Tasks.foreach with a CloseableIterable; an IOException while closing/reading the iterable during parallel loading is wrapped in RuntimeIOException with message 'Failed to close'. The deletes index therefore fails to build.","triggerScenarios":"Building a DeleteFileIndex (e.g. via files() during a scan) where reading or closing a delete-manifest stream throws IOException — storage outage, deleted/missing manifest, credentials revoked mid-scan.","commonSituations":"S3/GCS transient errors during large delete-index loads; concurrent snapshot expiration deleting manifests while a scan plans; misconfigured FileIO credentials.","solutions":["Inspect the cause (e.getCause()) for the underlying IOException and fix storage access/credentials.","Retry the scan; transient cloud storage errors often resolve.","Ensure snapshot expiry is not racing with scans; stop expiry during active query windows.","Verify delete manifests referenced by the snapshot still exist and are readable."],"exampleFix":"// before\nCloseableIterable<...> items = ...; // leaked, failure occurs on implicit close\n// after\ntry (CloseableIterable<...> items = ...) {\n  ... // ensure proper resource handling around manifest reads\n}","handlingStrategy":"retry","validationCode":"// before scanning, verify delete manifests are present\ntable.operations().current().currentSnapshot().dataManifests(table.io())\n    .forEach(m -> Preconditions.check(table.io().newInputFile(m.path()).exists(), \"missing \" + m.path()));","typeGuard":null,"tryCatchPattern":"try { CloseableIterable<DeleteFile> f = index.files(); } catch (RuntimeIOException e) {\n  LOG.error(\"delete index load failed\", e.getCause());\n  throw e;\n}","preventionTips":["Avoid concurrent snapshot expiration during scans.","Use retrying object-store clients for transient IO errors.","Monitor manifest lifecycle vs. long-running scans."],"tags":["io","delete-files","index"],"backgroundTag":"file-read-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"}