apache/hadoop · warning · RenameFailedException
dest is root directory
Error message
dest is root directory
What it means
initiateRename() maps dst to an S3 key; an empty dstKey means the destination is the bucket root. Renaming anything onto s3a://bucket/ is meaningless, so RenameFailedException 'dest is root directory' is thrown; rename() catches it, logs INFO, and returns false (default exit code).
Source
Thrown at hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3AFileSystem.java:2438
* @throws RenameFailedException if some criteria for a state changing
* rename was not met. This means work didn't happen; it's not something
* which is reported upstream to the FileSystem APIs, for which the semantics
* of "false" are pretty vague.
* @throws FileNotFoundException there's no source file.
* @throws IOException on IO failure.
*/
@Retries.RetryTranslated
private Pair<S3AFileStatus, S3AFileStatus> initiateRename(
final Path src,
final Path dst) throws IOException {
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);View on GitHub (pinned to 2add963021)
Solutions
- Build an explicit destination under root: new Path(new Path("/"), src.getName())
- Fix destination computation so the last path element is preserved
- Check dst.isRoot() before calling rename
Example fix
// before
Path dst = new Path("/");
fs.rename(src, dst);
// after: keep the file name at bucket top level
Path dst = new Path(new Path("/"), src.getName());
fs.rename(src, dst); Defensive patterns
Strategy: validation
Validate before calling
if (dst.isRoot()) {
dst = new Path(new Path("/"), src.getName());
}
fs.rename(src, dst); Prevention
- Always build destinations as new Path(dir, src.getName())
- Assert the destination has a non-empty last element in rename wrappers
- Remember the failure mode is rename()==false with an INFO log, not an exception
When it happens
Trigger: rename(src, new Path("/")) or any dst qualifying to the bucket root; 'move file to top level' logic that drops the filename when building the destination.
Common situations: Destination built as dst.getParent() of a top-level path; normalization dropping the last path element; code assuming rename-to-directory semantics where the directory is the root itself.
Related errors
- source is root directory
- Can't create root path
- source and dest refer to the same file or 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/95cf297ff5fa9c72.
Report an issue: GitHub.