apache/hadoop · error · FileAlreadyExistsException
Cannot rename symlink {} to its target {}
Error message
Cannot rename symlink {} to its target {} What it means
FileAlreadyExistsException thrown when renaming a symlink to the exact path the symlink points to. Such a rename would create a self-referential entry (the link resolving through itself), so validateDestination rejects it before any other destination check.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirRenameOp.java:548
} finally {
fsd.writeUnlock();
}
if (renameIIP != null) {
fsd.getEditLog().logRename(
srcIIP.getPath(), dstIIP.getPath(), mtime, logRetryCache);
}
// this rename never overwrites the dest so files deleted and collected
// are irrelevant.
return createRenameResult(fsd, renameIIP, false, null);
}
private static void validateDestination(
String src, String dst, INode srcInode)
throws IOException {
String error;
if (srcInode.isSymlink() &&
dst.equals(srcInode.asSymlink().getSymlinkString())) {
throw new FileAlreadyExistsException("Cannot rename symlink " + src
+ " to its target " + dst);
}
// dst cannot be a directory or a file under src
if (dst.startsWith(src)
&& dst.charAt(src.length()) == Path.SEPARATOR_CHAR) {
error = "Rename destination " + dst
+ " is a directory or file under source " + src;
NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: "
+ error);
throw new IOException(error);
}
if (FSDirectory.isExactReservedName(src)
|| FSDirectory.isExactReservedName(dst)) {
error = "Cannot rename to or from /.reserved";
throw new InvalidPathException(error);
}
}View on GitHub (pinned to 2add963021)
Solutions
- Rename the link to a different path, or delete the link if only the target is wanted.
- Guard in code: resolve the link target (getFileLinkStatus/getSymlink) and compare it with the destination before renaming.
Example fix
// before
fs.rename(linkPath, targetPath); // FileAlreadyExistsException: Cannot rename symlink to its target
// after
if (fs.getFileLinkStatus(linkPath).isSymlink()
&& targetPath.makeQualified(fs.getUri(), fs.getWorkingDirectory()).equals(
fs.getLinkTarget(linkPath).makeQualified(fs.getUri(), linkPath.getParent()))) {
// refuse: would rename a symlink onto its own target
} else {
fs.rename(linkPath, targetPath);
} Defensive patterns
Strategy: validation
Validate before calling
if (fs.getFileLinkStatus(src).isSymlink()) {
Path target = fs.getLinkTarget(src).makeQualified(fs.getUri(), src.getParent());
Path qdst = dst.makeQualified(fs.getUri(), fs.getWorkingDirectory());
if (target.equals(qdst)) {
throw new FileAlreadyExistsException("Refusing to rename symlink onto its own target");
}
}
fs.rename(src, dst); Try / catch
try {
fs.rename(src, dst);
} catch (FileAlreadyExistsException e) {
if (e.getMessage() != null && e.getMessage().contains("to its target")) {
// renaming a link onto its own target: pick another destination or delete the link
}
throw e;
} Prevention
- Resolve link targets before renaming symlinks.
- Skip symlinks in generic tree-move tools or handle them explicitly.
When it happens
Trigger: `hdfs dfs -mv /link /target` where /link's stored target string is exactly /target; automation that 'normalizes' symlinks by moving them onto the files they reference; link-farm reorganization scripts.
Common situations: Symlinked warehouse layouts being flattened; tools that rename links assuming posix mv-into-directory semantics; snapshot copies where links and targets collide.
Related errors
- The source {} and destination {} are the same
- File: %s already exists
- Failed to rename since the dest path %s already exists.
- The source {src} and destination {dst} are the same
- Cannot rename symlink {src} to its target {dst}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/1343b02062ab0931.
Report an issue: GitHub.