apache/hadoop · warning · RenameFailedException
source is root directory
Error message
source is root directory
What it means
initiateRename() maps src to an S3 key; an empty srcKey means the source is the bucket root (s3a://bucket/), which cannot be renamed. RenameFailedException 'source is root directory' is thrown; rename() catches it, logs at INFO and returns the exception's exit code (false here), so callers observe rename(...) returning false rather than an IOException.
Source
Thrown at hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3AFileSystem.java:2435
* @param src qualified path to be renamed
* @param dst qualified path after rename
* @return the source and (possibly null) destination status entries.
* @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());
}
View on GitHub (pinned to 2add963021)
Solutions
- Fix the caller to rename a non-root source path
- To relocate everything under root, list the root and rename each child individually
- Guard with src.isRoot() before calling rename and fail with a clear message
Example fix
// before
boolean ok = fs.rename(new Path("/"), dst);
// after: refuse root sources up front
if (src.isRoot()) {
throw new IllegalArgumentException("cannot rename the bucket root: " + src);
}
boolean ok = fs.rename(src, dst); Defensive patterns
Strategy: validation
Validate before calling
if (src.isRoot()) {
throw new IllegalArgumentException("cannot rename bucket root as source");
} Prevention
- Validate !src.isRoot() in rename wrappers
- Compute sources from listings of children rather than parents of top-level entries
- Check rename's boolean return - root-source failures surface as false with an INFO log, not as exceptions
When it happens
Trigger: rename(new Path("/"), dst) or any src that qualifies to the bucket root; src computed via getParent() on a top-level file.
Common situations: Directory-walking code that ends up renaming a parent; attempts to 'move the whole bucket' by renaming its root; off-by-one path arithmetic landing on root.
Related errors
- dest 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/b5acc52f478f839c.
Report an issue: GitHub.