apache/hadoop · error · IOException
Failed to rename %s to %s, %s is a file
Error message
Failed to rename %s to %s, %s is a file
What it means
Thrown by AliyunOSSFileSystem.rename(): the destination path itself does not exist, so the code stats the destination's parent and requires it to be a directory. When that parent exists but is a file, the renamed object would land 'inside' a file key, which OSS cannot represent, so it throws IOException("Failed to rename %s to %s, %s is a file").
Source
Thrown at hadoop-tools/hadoop-aliyun/src/main/java/org/apache/hadoop/fs/aliyun/oss/AliyunOSSFileSystem.java:647
Path parent = dstPath.getParent();
while (parent != null && !srcPath.equals(parent)) {
parent = parent.getParent();
}
if (parent != null) {
return false;
}
FileStatus srcStatus = getFileStatus(srcPath);
FileStatus dstStatus;
try {
dstStatus = getFileStatus(dstPath);
} catch (FileNotFoundException fnde) {
dstStatus = null;
}
if (dstStatus == null) {
// If dst doesn't exist, check whether dst dir exists or not
dstStatus = getFileStatus(dstPath.getParent());
if (!dstStatus.isDirectory()) {
throw new IOException(String.format(
"Failed to rename %s to %s, %s is a file", srcPath, dstPath,
dstPath.getParent()));
}
} else {
if (srcStatus.getPath().equals(dstStatus.getPath())) {
return !srcStatus.isDirectory();
} else if (dstStatus.isDirectory()) {
// If dst is a directory
dstPath = new Path(dstPath, srcPath.getName());
FileStatus[] statuses;
try {
statuses = listStatus(dstPath);
} catch (FileNotFoundException fnde) {
statuses = null;
}
if (statuses != null && statuses.length > 0) {
// If dst exists and not a directory / not empty
throw new FileAlreadyExistsException(String.format(View on GitHub (pinned to 2add963021)
Solutions
- Delete or rename the file object at the parent path so the directory structure can exist, then retry the rename
- Correct the destination path if the parent was mistyped
- Create the destination directory first (fs.mkdirs(dst.getParent())) after resolving the conflict
Example fix
// before
fs.rename(new Path("oss://b/f"), new Path("oss://b/a/g")); // 'a' is a file
// after
// resolve 'a': remove the file, then ensure the directory exists
fs.delete(new Path("oss://b/a"), false);
fs.mkdirs(new Path("oss://b/a"));
fs.rename(new Path("oss://b/f"), new Path("oss://b/a/g")); Defensive patterns
Strategy: validation
Validate before calling
Path parent = dst.getParent();
if (!fs.exists(dst)) {
if (!fs.exists(parent) || !fs.getFileStatus(parent).isDirectory()) {
throw new IOException("rename dst parent is not a directory: " + parent);
}
}
fs.rename(src, dst); Try / catch
catch (IOException e) { if (e.getMessage().contains("is a file")) { /* clean the file at dst parent or fix dst path */ } throw e; } Prevention
- Validate the destination parent is an existing directory before rename
- Keep partition directories free of file objects at the same key
When it happens
Trigger: Calling rename(src, dst) where dst is absent and dst.getParent() exists as a file object — e.g., rename(oss://bucket/f, oss://bucket/a/g) while 'a' is a file; typically from committers or Hive moving files into partition paths.
Common situations: Partition directories whose prefix is occupied by an old data file; staging/commit moves into paths whose parents were written as files by other tools; renaming to a mistyped destination under a file-like prefix.
Related errors
- Not a directory: {parent}
- Failed to rename %s to %s, file already exists or not empty!
- Failed to rename %s to %s, file already exists!
- rename destination parent ${parent} is a file.
- rename destination parent {} is a file.
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/48faef9e9e8732dc.
Report an issue: GitHub.