{"record":{"id":"f36a81bf360288db","repo":"apache/hadoop","slug":"source-srcfile-and-destination-destfile-ar","errorCode":null,"errorMessage":"Source '{srcFile}' and destination '{destFile}' are the same","messagePattern":"Source '(.+?)' and destination '(.+?)' are the same","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/Storage.java","lineNumber":1339,"sourceCode":"   * @throws IOException if source or destination is invalid\n   * @throws IOException if an IO error occurs during copying\n   */\n  public static void nativeCopyFileUnbuffered(File srcFile, File destFile,\n      boolean preserveFileDate) throws IOException {\n    if (srcFile == null) {\n      throw new NullPointerException(\"Source must not be null\");\n    }\n    if (destFile == null) {\n      throw new NullPointerException(\"Destination must not be null\");\n    }\n    if (srcFile.exists() == false) {\n      throw new FileNotFoundException(\"Source '\" + srcFile + \"' does not exist\");\n    }\n    if (srcFile.isDirectory()) {\n      throw new IOException(\"Source '\" + srcFile + \"' exists but is a directory\");\n    }\n    if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) {\n      throw new IOException(\"Source '\" + srcFile + \"' and destination '\" +\n          destFile + \"' are the same\");\n    }\n    File parentFile = destFile.getParentFile();\n    if (parentFile != null) {\n      if (!parentFile.mkdirs() && !parentFile.isDirectory()) {\n        throw new IOException(\"Destination '\" + parentFile\n            + \"' directory cannot be created\");\n      }\n    }\n    if (destFile.exists()) {\n      if (FileUtil.canWrite(destFile) == false) {\n        throw new IOException(\"Destination '\" + destFile\n            + \"' exists but is read-only\");\n      } else {\n        if (destFile.delete() == false) {\n          throw new IOException(\"Destination '\" + destFile\n              + \"' exists but cannot be deleted\");\n        }","sourceCodeStart":1321,"sourceCodeEnd":1357,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/Storage.java#L1321-L1357","documentation":"Guard clause of Storage.nativeCopyFileUnbuffered: getCanonicalPath() of source and destination are equal, so the copy would read and write the same file. Canonical comparison resolves symlinks and relative segments, catching indirect self-copies a plain equals would miss.","triggerScenarios":"src and dest are the same path, or differ only via symlink, '..', or case-insensitive filesystem spelling; backup logic that falls back to the original path when the backup path is unset.","commonSituations":"Defaulted backup/destination config that silently equals the source; symlinked storage dirs (dst is a symlink to src); rotating-file logic that degrades to no-op paths.","solutions":["Write to a distinct destination (e.g. a temp file in the same directory) and move it afterwards","Skip the copy when the canonical paths match instead of erroring","Fix the configuration lookup that produced the identical destination"],"exampleFix":"// before\nStorage.nativeCopyFileUnbuffered(src, dst == null ? src : dst, true);\n// after\nif (src.getCanonicalPath().equals(dst.getCanonicalPath())) return;\nStorage.nativeCopyFileUnbuffered(src, dst, true);","handlingStrategy":"validation","validationCode":"if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) {\n  return; // self-copy is a no-op, not an error\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Compare canonical paths before any copy in your own wrapper","Resolve symlinks in storage-dir config once at startup to expose aliases early","Give backup/destination settings a distinct mandatory default instead of falling back to the source path"],"tags":["hdfs","file-copy","path-validation","symlink"],"backgroundTag":"same-source-destination","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}