{"record":{"id":"07aaf1b2c202fbf2","repo":"apache/hadoop","slug":"could-not-delete-original-file","errorCode":null,"errorMessage":"Could not delete original file {}","messagePattern":"Could not delete original file (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/util/AtomicFileOutputStream.java","lineNumber":88,"sourceCode":"  public void close() throws IOException {\n    boolean triedToClose = false, success = false;\n    try {\n      flush();\n      ((FileOutputStream)out).getChannel().force(true);\n\n      triedToClose = true;\n      super.close();\n      success = true;\n    } finally {\n      if (success) {\n        boolean renamed = tmpFile.renameTo(origFile);\n        if (!renamed) {\n          // On windows, renameTo does not replace.\n          if (origFile.exists()) {\n            try {\n              Files.delete(origFile.toPath());\n            } catch (IOException e) {\n              throw new IOException(\"Could not delete original file \" + origFile, e);\n            }\n          }\n          try {\n            NativeIO.renameTo(tmpFile, origFile);\n          } catch (NativeIOException e) {\n            throw new IOException(\"Could not rename temporary file \" + tmpFile\n              + \" to \" + origFile + \" due to failure in native rename. \"\n              + e.toString());\n          }\n        }\n      } else {\n        if (!triedToClose) {\n          // If we failed when flushing, try to close it to not leak an FD\n          IOUtils.closeStream(out);\n        }\n        // close wasn't successful, try to delete the tmp file\n        if (!tmpFile.delete()) {\n          LOG.warn(\"Unable to delete tmp file \" + tmpFile);","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/util/AtomicFileOutputStream.java#L70-L106","documentation":"AtomicFileOutputStream writes to a temp file and renames it over the destination on close(). File.renameTo does not replace an existing target on Windows, so when the plain rename fails it deletes the original first — and that delete threw. On Windows this almost always means another process holds the target open (editor, antivirus, indexer, another JVM) or the user lacks delete permission; two concurrent writers to the same path produce the same collision.","triggerScenarios":"close() of an AtomicFileOutputStream whose destination already exists and is locked by another process (Windows file locking), delete-denied by ACLs, or concurrently written by a second thread/process.","commonSituations":"Hadoop-on-Windows dev machines; antivirus real-time scanning of the output directory; parallel tests writing the same file.","solutions":["Close whatever holds the file (editors, tail processes) or exclude the output directory from antivirus real-time scanning, then rerun","Delete the destination before the write so the plain renameTo path succeeds: Files.deleteIfExists(dest)","Ensure a single writer per destination path; on Windows verify the user has Modify/Delete rights on the file"],"exampleFix":"// before: target may be locked on Windows\ntry (AtomicFileOutputStream out = new AtomicFileOutputStream(file)) {\n  ...\n} // IOException: Could not delete original file ...\n\n// after: clear the destination so no delete-replace is needed\nFiles.deleteIfExists(file.toPath());\ntry (AtomicFileOutputStream out = new AtomicFileOutputStream(file)) {\n  ...\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try (AtomicFileOutputStream out = new AtomicFileOutputStream(file)) {\n  // write\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Could not delete original file\")) {\n    // Windows: target locked or delete-denied — free the lock, then retry once\n    LOG.error(\"target {} locked or undeletable; close holders and retry\", file, e);\n  }\n  throw e;\n}","preventionTips":["Ensure a single writer per destination path; serialize writers with a lock if needed","On Windows, exclude output directories from antivirus real-time scanning","Delete the destination beforehand so the plain renameTo path never needs a replace","Always close AtomicFileOutputStream via try-with-resources so close() runs exactly once"],"tags":["hadoop","io","windows","file-lock","atomic-write"],"backgroundTag":"file-locked-by-process","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}