{"record":{"id":"4305d2f7157d9406","repo":"apache/hadoop","slug":"rename-destination-dst-already-exists","errorCode":null,"errorMessage":"Rename destination {dst} already exists.","messagePattern":"Rename destination (.+?) already exists\\.","errorType":"exception","errorClass":"FileAlreadyExistsException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/AbstractFileSystem.java","lineNumber":876,"sourceCode":"    } catch (IOException e) {\n      dstStatus = null;\n    }\n    if (dstStatus != null) {\n      if (dst.equals(src)) {\n        throw new FileAlreadyExistsException(\n            \"The source \"+src+\" and destination \"+dst+\" are the same\");\n      }\n      if (srcStatus.isSymlink() && dst.equals(srcStatus.getSymlink())) {\n        throw new FileAlreadyExistsException(\n            \"Cannot rename symlink \"+src+\" to its target \"+dst);\n      }\n      // It's OK to rename a file to a symlink and vice versa\n      if (srcStatus.isDirectory() != dstStatus.isDirectory()) {\n        throw new IOException(\"Source \" + src + \" and destination \" + dst\n            + \" must both be directories\");\n      }\n      if (!overwrite) {\n        throw new FileAlreadyExistsException(\"Rename destination \" + dst\n            + \" already exists.\");\n      }\n      // Delete the destination that is a file or an empty directory\n      if (dstStatus.isDirectory()) {\n        RemoteIterator<FileStatus> list = listStatusIterator(dst);\n        if (list != null && list.hasNext()) {\n          throw new IOException(\n              \"Rename cannot overwrite non empty destination directory \" + dst);\n        }\n      }\n      delete(dst, false);\n    } else {\n      final Path parent = dst.getParent();\n      final FileStatus parentStatus = getFileStatus(parent);\n      if (parentStatus.isFile()) {\n        throw new ParentNotDirectoryException(\"Rename destination parent \"\n            + parent + \" is a file.\");\n      }","sourceCodeStart":858,"sourceCodeEnd":894,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/AbstractFileSystem.java#L858-L894","documentation":"Non-overwrite rename is POSIX-like: if the destination already exists, AbstractFileSystem.renameInternal throws FileAlreadyExistsException before touching anything. FileContext.rename(src, dst) without options maps to Rename.NONE, so any pre-existing file, directory, or symlink at dst triggers it.","triggerScenarios":"fc.rename(src, dst) (Rename.NONE) with dst already present; two tasks racing to rename different sources onto the same target; second execution of an idempotent job writing to a fixed path.","commonSituations":"Re-running ingestion jobs that stage into a constant destination; concurrent writers in the same directory; leftover output from a killed previous run occupying the target name.","solutions":["If replacement is intended, pass Options.Rename.OVERWRITE: fc.rename(src, dst, Rename.OVERWRITE)","If not, pick a unique destination (append timestamp/UUID) or delete dst before renaming","For race-prone targets, serialize renames or catch FileAlreadyExistsException and pick a new name instead of retrying blindly"],"exampleFix":"// before\nfc.rename(src, dst); // dst exists -> FileAlreadyExistsException\n\n// after\nfc.rename(src, dst, Options.Rename.OVERWRITE);\n// or: fc.delete(dst, true); fc.rename(src, dst);","handlingStrategy":"validation","validationCode":"if (fc.util().exists(dst)) {\n  fc.delete(dst, true); // or pass Options.Rename.OVERWRITE, or pick a new name\n}","typeGuard":null,"tryCatchPattern":"catch (FileAlreadyExistsException e) { /* rename with Rename.OVERWRITE if replacement is safe, else choose a unique name */ }","preventionTips":["Decide explicitly per call site whether rename replaces: pass Rename.OVERWRITE, do not rely on the default","Use deterministic unique destinations (append run id / timestamp) for concurrent writers","Catch FileAlreadyExistsException as the expected signal of a lost race, not as a crash"],"tags":["rename","filealreadyexists","filecontext","hadoop-fs"],"backgroundTag":"file-already-exists","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}