apache/hadoop · info · RenameFailedException
source and dest refer to the same file or directory
Error message
source and dest refer to the same file or directory
What it means
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.
Source
Thrown at hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3AFileSystem.java:2449
String srcKey = pathToKey(src);
String dstKey = pathToKey(dst);
if (srcKey.isEmpty()) {
throw new RenameFailedException(src, dst, "source is root directory");
}
if (dstKey.isEmpty()) {
throw new RenameFailedException(src, dst, "dest is root directory");
}
// get the source file status; this raises a FNFE if there is no source
// file.
S3AFileStatus srcStatus = innerGetFileStatus(src, true,
StatusProbeEnum.ALL);
if (srcKey.equals(dstKey)) {
LOG.debug("rename: src and dest refer to the same file or directory: {}",
dst);
throw new RenameFailedException(src, dst,
"source and dest refer to the same file or directory")
.withExitCode(srcStatus.isFile());
}
S3AFileStatus dstStatus = null;
try {
dstStatus = innerGetFileStatus(dst, true, StatusProbeEnum.ALL);
// if there is no destination entry, an exception is raised.
// hence this code sequence can assume that there is something
// at the end of the path; the only detail being what it is and
// whether or not it can be the destination of the rename.
if (srcStatus.isDirectory()) {
if (dstStatus.isFile()) {
throw new FileAlreadyExistsException(
"Failed to rename " + src + " to " + dst
+"; source is a directory and dest is a file");
} else if (dstStatus.isEmptyDirectory() != Tristate.TRUE) {
throw new RenameFailedException(src, dst,View on GitHub (pinned to 2add963021)
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
Example fix
// before: may issue a self-rename on retry
fs.rename(src, dst);
// after: short-circuit identical destinations
if (src.makeQualified(fs).equals(dst.makeQualified(fs))) {
return true;
}
return fs.rename(src, dst); Defensive patterns
Strategy: validation
Validate before calling
// Skip self-renames before invoking the FS
if (src.makeQualified(fs).equals(dst.makeQualified(fs))) {
return true; // already at destination
}
return fs.rename(src, dst); Prevention
- 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
When it happens
Trigger: 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.
Common situations: Idempotent retry wrappers re-running finished moves; two code paths normalizing the same path differently; case-sensitivity assumptions ported from other filesystems.
Related errors
- Move destination must be different from source for %s.
- source is root directory
- dest is root directory
- Failed to rename <src> to <dst>; source is a directory and d
- Destination is a non-empty directory
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/768b466ae613b491.
Report an issue: GitHub.