{"record":{"id":"768b466ae613b491","repo":"apache/hadoop","slug":"source-and-dest-refer-to-the-same-file-or-director","errorCode":null,"errorMessage":"source and dest refer to the same file or directory","messagePattern":"source and dest refer to the same file or directory","errorType":"exception","errorClass":"RenameFailedException","httpStatus":null,"severity":"info","filePath":"hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3AFileSystem.java","lineNumber":2449,"sourceCode":"    String srcKey = pathToKey(src);\n    String dstKey = pathToKey(dst);\n\n    if (srcKey.isEmpty()) {\n      throw new RenameFailedException(src, dst, \"source is root directory\");\n    }\n    if (dstKey.isEmpty()) {\n      throw new RenameFailedException(src, dst, \"dest is root directory\");\n    }\n\n    // get the source file status; this raises a FNFE if there is no source\n    // file.\n    S3AFileStatus srcStatus = innerGetFileStatus(src, true,\n        StatusProbeEnum.ALL);\n\n    if (srcKey.equals(dstKey)) {\n      LOG.debug(\"rename: src and dest refer to the same file or directory: {}\",\n          dst);\n      throw new RenameFailedException(src, dst,\n          \"source and dest refer to the same file or directory\")\n          .withExitCode(srcStatus.isFile());\n    }\n\n    S3AFileStatus dstStatus = null;\n    try {\n      dstStatus = innerGetFileStatus(dst, true, StatusProbeEnum.ALL);\n      // if there is no destination entry, an exception is raised.\n      // hence this code sequence can assume that there is something\n      // at the end of the path; the only detail being what it is and\n      // whether or not it can be the destination of the rename.\n      if (srcStatus.isDirectory()) {\n        if (dstStatus.isFile()) {\n          throw new FileAlreadyExistsException(\n              \"Failed to rename \" + src + \" to \" + dst\n               +\"; source is a directory and dest is a file\");\n        } else if (dstStatus.isEmptyDirectory() != Tristate.TRUE) {\n          throw new RenameFailedException(src, dst,","sourceCodeStart":2431,"sourceCodeEnd":2467,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3AFileSystem.java#L2431-L2467","documentation":"In initiateRename(), srcKey.equals(dstKey) means source and destination resolve to the same S3 key, so the rename is a no-op. The code throws RenameFailedException 'source and dest refer to the same file or directory' with exit code srcStatus.isFile(): rename() catches it and returns that code - true when the source is a file (POSIX rename onto itself succeeds) and false when it is a directory. It is logged at INFO, never raised to the caller.","triggerScenarios":"rename(src, src); src and dst strings that qualify to the same key (trailing slash, duplicated slashes, different URI encodings); retry logic re-invoking an already-completed rename.","commonSituations":"Idempotent retry wrappers re-running finished moves; two code paths normalizing the same path differently; case-sensitivity assumptions ported from other filesystems.","solutions":["Treat rename(p, p) as success for files - the exit code already does; for directories skip the call","Qualify both paths (src.makeQualified(fs)) and compare before renaming to avoid the no-op branch","Log src/dst keys when debugging surprising rename results"],"exampleFix":"// before: may issue a self-rename on retry\nfs.rename(src, dst);\n\n// after: short-circuit identical destinations\nif (src.makeQualified(fs).equals(dst.makeQualified(fs))) {\n  return true;\n}\nreturn fs.rename(src, dst);","handlingStrategy":"validation","validationCode":"// Skip self-renames before invoking the FS\nif (src.makeQualified(fs).equals(dst.makeQualified(fs))) {\n  return true; // already at destination\n}\nreturn fs.rename(src, dst);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Qualify and normalize paths once at ingestion; compare qualified forms","Make retry wrappers idempotent: check destination before re-invoking rename","When rename returns false, log both qualified paths to spot self-renames"],"tags":["s3a","rename","no-op","idempotency"],"backgroundTag":"same-source-and-destination","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}