{"record":{"id":"f3555eeb79f03adc","repo":"apache/hadoop","slug":"destination-path-dst-already-exists","errorCode":null,"errorMessage":"Destination path {dst} already exists","messagePattern":"Destination path (.+?) already exists","errorType":"exception","errorClass":"FileAlreadyExistsException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/ftp/FTPFileSystem.java","lineNumber":685,"sourceCode":"   * @return\n   * @throws IOException\n   */\n  @SuppressWarnings(\"deprecation\")\n  private boolean rename(FTPClient client, Path src, Path dst)\n      throws IOException {\n    Path workDir = new Path(client.printWorkingDirectory());\n    Path absoluteSrc = makeAbsolute(workDir, src);\n    Path absoluteDst = makeAbsolute(workDir, dst);\n    if (!exists(client, absoluteSrc)) {\n      throw new FileNotFoundException(\"Source path \" + src + \" does not exist\");\n    }\n    if (isDirectory(absoluteDst)) {\n      // destination is a directory: rename goes underneath it with the\n      // source name\n      absoluteDst = new Path(absoluteDst, absoluteSrc.getName());\n    }\n    if (exists(client, absoluteDst)) {\n      throw new FileAlreadyExistsException(\"Destination path \" + dst\n          + \" already exists\");\n    }\n    URI parentSrc = absoluteSrc.getParent().toUri();\n    URI parentDst = absoluteDst.getParent().toUri();\n    if (isParentOf(absoluteSrc, absoluteDst)) {\n      throw new IOException(\"Cannot rename \" + absoluteSrc + \" under itself\"\n      + \" : \"+ absoluteDst);\n    }\n\n    if (!parentSrc.toString().equals(parentDst.toString())) {\n      throw new IOException(\"Cannot rename source: \" + absoluteSrc\n          + \" to \" + absoluteDst\n          + \" -\"+ E_SAME_DIRECTORY_ONLY);\n    }\n    String from = absoluteSrc.getName();\n    String to = absoluteDst.getName();\n    client.changeWorkingDirectory(parentSrc.getPath());\n    boolean renamed = client.rename(from, to);","sourceCodeStart":667,"sourceCodeEnd":703,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/ftp/FTPFileSystem.java#L667-L703","documentation":"rename() never overwrites: after resolving the destination — including the rule that a directory dst becomes dst/srcName — it probes existence and throws FileAlreadyExistsException(\"Destination path <dst> already exists\"). This mirrors HDFS rename semantics where the target must not be clobbered.","triggerScenarios":"rename(a, b) with b already present; rename(a, dir) where dir/a already exists because of the dst-directory expansion rule; a racing writer creating the target between your exists() check and the rename.","commonSituations":"Idempotent job reruns writing to the same output name; ingest pipelines that \"move into place\" without unique names; developers assuming POSIX mv overwrite semantics.","solutions":["Choose a unique destination (timestamp/UUID suffix) or delete/backup the target first when overwrite is intended","Remember the expansion rule: when dst is a directory the real checked path is dst/srcName — check that path","Re-check fs.exists(dst) right before rename and accept the small race window with a retry","For atomic publish patterns, rename into a fresh directory instead of over existing files"],"exampleFix":"// before\nfs.rename(src, dst);  // FileAlreadyExistsException\n\n// after\nif (fs.exists(dst)) {\n  Path backup = new Path(dst.getParent(), dst.getName() + \".\" + System.currentTimeMillis());\n  fs.rename(dst, backup);   // or fs.delete(dst, false) if overwrite is truly wanted\n}\nfs.rename(src, dst);","handlingStrategy":"validation","validationCode":"// pick a non-colliding destination (remember: dst-dir expands to dst/srcName)\nPath target = fs.exists(dst) || fs.exists(new Path(dst, src.getName()))\n    ? new Path(dst.getParent(), dst.getName() + \".\" + System.currentTimeMillis())\n    : dst;\nfs.rename(src, target);","typeGuard":null,"tryCatchPattern":"catch FileAlreadyExistsException specifically and respond by choosing a new destination or removing the target — do not retry the same rename unchanged.","preventionTips":["Never assume POSIX mv overwrite semantics on Hadoop filesystems","When dst is a directory, remember the checked path is dst/srcName","Make output names unique (job id, timestamp) for rerunnable jobs"],"tags":["ftp","hadoop","rename","file-exists"],"backgroundTag":"file-already-exists","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}