apache/hadoop · error · IOException
Source '{srcFile}' and destination '{destFile}' are the same
Error message
Source '{srcFile}' and destination '{destFile}' are the same What it means
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.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/Storage.java:1339
* @throws IOException if source or destination is invalid
* @throws IOException if an IO error occurs during copying
*/
public static void nativeCopyFileUnbuffered(File srcFile, File destFile,
boolean preserveFileDate) throws IOException {
if (srcFile == null) {
throw new NullPointerException("Source must not be null");
}
if (destFile == null) {
throw new NullPointerException("Destination must not be null");
}
if (srcFile.exists() == false) {
throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
}
if (srcFile.isDirectory()) {
throw new IOException("Source '" + srcFile + "' exists but is a directory");
}
if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) {
throw new IOException("Source '" + srcFile + "' and destination '" +
destFile + "' are the same");
}
File parentFile = destFile.getParentFile();
if (parentFile != null) {
if (!parentFile.mkdirs() && !parentFile.isDirectory()) {
throw new IOException("Destination '" + parentFile
+ "' directory cannot be created");
}
}
if (destFile.exists()) {
if (FileUtil.canWrite(destFile) == false) {
throw new IOException("Destination '" + destFile
+ "' exists but is read-only");
} else {
if (destFile.delete() == false) {
throw new IOException("Destination '" + destFile
+ "' exists but cannot be deleted");
}View on GitHub (pinned to 2add963021)
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
Example fix
// before Storage.nativeCopyFileUnbuffered(src, dst == null ? src : dst, true); // after if (src.getCanonicalPath().equals(dst.getCanonicalPath())) return; Storage.nativeCopyFileUnbuffered(src, dst, true);
Defensive patterns
Strategy: validation
Validate before calling
if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) {
return; // self-copy is a no-op, not an error
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Source '{srcFile}' exists but is a directory
- Filesystem does not support symlinks!
- Operation not supported
- Source must not be null
- Destination must not be null
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/f36a81bf360288db.
Report an issue: GitHub.