apache/hadoop · error · FileAlreadyExistsException
The source {} and destination {} are the same
Error message
The source {} and destination {} are the same What it means
FileAlreadyExistsException from renameToInt when source and destination resolve to the exact same path. Rename-to-self is rejected up front during destination validation, before overwrite checks - even Options.Rename.OVERWRITE cannot make it meaningful (it would delete the source).
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirRenameOp.java:398
*/
static RenameResult unprotectedRenameTo(FSDirectory fsd,
final INodesInPath srcIIP, final INodesInPath dstIIP, long timestamp,
BlocksMapUpdateInfo collectedBlocks, Options.Rename... options)
throws IOException {
assert fsd.hasWriteLock();
boolean overwrite = options != null
&& Arrays.asList(options).contains(Options.Rename.OVERWRITE);
final String src = srcIIP.getPath();
final String dst = dstIIP.getPath();
final String error;
final INode srcInode = srcIIP.getLastINode();
List<INodeDirectory> srcSnapshottableDirs = new ArrayList<>();
validateRenameSource(fsd, srcIIP, srcSnapshottableDirs);
// validate the destination
if (dst.equals(src)) {
throw new FileAlreadyExistsException("The source " + src +
" and destination " + dst + " are the same");
}
validateDestination(src, dst, srcInode);
if (dstIIP.length() == 1) {
error = "rename destination cannot be the root";
NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: " +
error);
throw new IOException(error);
}
BlockStoragePolicySuite bsps = fsd.getBlockStoragePolicySuite();
fsd.ezManager.checkMoveValidity(srcIIP, dstIIP);
final INode dstInode = dstIIP.getLastINode();
List<INodeDirectory> dstSnapshottableDirs = new ArrayList<>();
if (dstInode != null) { // Destination exists
validateOverwrite(src, dst, overwrite, srcInode, dstInode);
FSDirSnapshotOp.checkSnapshot(fsd, dstIIP, dstSnapshottableDirs);View on GitHub (pinned to 2add963021)
Solutions
- Fix the caller to pass a genuinely different destination path.
- Guard in code: compare qualified src and dst and treat equality as a no-op.
- Inspect the job's configuration for miswired source/destination parameters.
Example fix
// before
fs.rename(src, dst); // src and dst qualified to the same path
// after
if (!src.makeQualified(fs.getUri(), fs.getWorkingDirectory())
.equals(dst.makeQualified(fs.getUri(), fs.getWorkingDirectory()))) {
fs.rename(src, dst);
} Defensive patterns
Strategy: validation
Validate before calling
Path qs = src.makeQualified(fs.getUri(), fs.getWorkingDirectory());
Path qd = dst.makeQualified(fs.getUri(), fs.getWorkingDirectory());
if (qs.equals(qd)) {
return; // src == dst: nothing to do
}
fs.rename(src, dst); Try / catch
try {
fs.rename(src, dst);
} catch (FileAlreadyExistsException e) {
if (src.makeQualified(fs.getUri(), fs.getWorkingDirectory())
.equals(dst.makeQualified(fs.getUri(), fs.getWorkingDirectory()))) {
return; // no-op, ignore
}
throw e;
} Prevention
- Compare qualified (URI + working-dir resolved) paths before any rename.
- Validate src/dst config pairs at job submission time.
When it happens
Trigger: `hdfs dfs -mv /a /a`; programmatic fs.rename(src, dst) where both Paths are equal after qualification (same URI, no trailing-slash difference); templated pipelines substituting identical src/dst values from config.
Common situations: Config-driven promotion pipelines where the source and destination variables collapse to the same value (same table rename, env-to-env copy with matching envs); path normalization differences hiding the equality from the caller but not the NameNode.
Related errors
- rename destination cannot be the root
- Cannot rename symlink {} to its target {}
- Rename destination {} is a directory or file under source {}
- Invalid parameter value: destination = "{str}" is not an abs
- File: %s already exists
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/0bc515b3551767a6.
Report an issue: GitHub.