{"record":{"id":"9a34bd50b25e4c59","repo":"apache/iceberg","slug":"failed-to-delete-file-s","errorCode":null,"errorMessage":"Failed to delete file: %s","messagePattern":"Failed to delete file: (.+?)","errorType":"exception","errorClass":"RuntimeIOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/hadoop/HadoopCatalog.java","lineNumber":270,"sourceCode":"    }\n\n    Path tablePath = new Path(defaultWarehouseLocation(identifier));\n    TableOperations ops = newTableOps(identifier);\n    TableMetadata lastMetadata = ops.current();\n    try {\n      if (lastMetadata == null) {\n        LOG.debug(\"Not an iceberg table: {}\", identifier);\n        return false;\n      } else {\n        if (purge) {\n          // Since the data files and the metadata files may store in different locations,\n          // so it has to call dropTableData to force delete the data file.\n          CatalogUtil.dropTableData(ops.io(), lastMetadata);\n        }\n        return fs.delete(tablePath, true /* recursive */);\n      }\n    } catch (IOException e) {\n      throw new RuntimeIOException(e, \"Failed to delete file: %s\", tablePath);\n    }\n  }\n\n  @Override\n  public void renameTable(TableIdentifier from, TableIdentifier to) {\n    throw new UnsupportedOperationException(\"Cannot rename Hadoop tables\");\n  }\n\n  @Override\n  public void createNamespace(Namespace namespace, Map<String, String> meta) {\n    Preconditions.checkArgument(\n        !namespace.isEmpty(), \"Cannot create namespace with invalid name: %s\", namespace);\n    if (!meta.isEmpty()) {\n      throw new UnsupportedOperationException(\n          \"Cannot create namespace \" + namespace + \": metadata is not supported\");\n    }\n\n    Path nsPath = new Path(warehouseLocation, SLASH.join(namespace.levels()));","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/hadoop/HadoopCatalog.java#L252-L288","documentation":"HadoopCatalog.dropTable wraps IOExceptions from the recursive table-directory delete into a RuntimeIOException. This happens after the table metadata was confirmed present (and possibly purged via dropTableData), so a failure can leave a partially deleted table: data files may be gone while the metadata directory remains.","triggerScenarios":"Calling catalog.dropTable(identifier, purge) when fs.delete(tablePath, true) throws IOException: filesystem unavailable, HDFS lease/permission issues, cloud-store throttling, or errors while dropTableData deletes data files in a different location.","commonSituations":"HDFS NameNode downtime mid-delete, S3 rate limiting (503 Slow Down) during bulk data-file deletion, permission revoked on the table directory, or object-store eventual consistency conflicts.","solutions":["Inspect the IOException cause; distinguish permission vs connectivity vs throttling errors.","Retry the dropTable call — it is safe to re-run: a second call finds metadata missing and returns false or completes cleanup.","For cloud stores, apply exponential backoff / retry policies and check for rate-limit errors.","Verify the caller has delete permission on the table directory and its parent.","If data files were purged but metadata remains, re-run dropTable with purge=false to remove leftover metadata."],"exampleFix":"// before: single attempt\nboolean dropped = catalog.dropTable(ident, true);\n\n// after: retry transient failures\ntry {\n  catalog.dropTable(ident, true);\n} catch (RuntimeIOException e) {\n  Tasks.foreach(ident).retry(3).suppressExceptions().run(i -> catalog.dropTable(i, true));\n}","handlingStrategy":"retry","validationCode":"// No pre-check possible for I/O failure; ensure table exists first:\nif (!catalog.tableExists(ident)) { return; }","typeGuard":null,"tryCatchPattern":"try { catalog.dropTable(ident, true); } catch (RuntimeIOException e) { Tasks.foreach(ident).retry(3).exponentialBackoff(100, 10000).run(i -> catalog.dropTable(i, true)); }","preventionTips":["Ensure delete permissions on table and parent directories","Use retry policies for cloud-store deletes","Re-run dropTable after partial failure — it is idempotent"],"tags":["io","filesystem","delete","drop-table","hadoop"],"backgroundTag":"file-delete-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"}