apache/hadoop · error · FileAlreadyExistsException
Can't make directory for path '%s', it is a file.
Error message
Can't make directory for path '%s', it is a file.
What it means
Thrown by AliyunOSSFileSystem.validatePath(), called from mkdirs after the target itself was not found. It walks every ancestor of the path; if any ancestor exists but is a file (not a directory), building the directory chain is impossible and it throws FileAlreadyExistsException("Can't make directory for path '%s', it is a file.") naming that ancestor.
Source
Thrown at hadoop-tools/hadoop-aliyun/src/main/java/org/apache/hadoop/fs/aliyun/oss/AliyunOSSFileSystem.java:596
}
}
/**
* Check whether the path is a valid path.
*
* @param path the path to be checked.
* @throws IOException
*/
private void validatePath(Path path) throws IOException {
Path fPart = path.getParent();
do {
try {
FileStatus fileStatus = getFileStatus(fPart);
if (fileStatus.isDirectory()) {
// If path exists and a directory, exit
break;
} else {
throw new FileAlreadyExistsException(String.format(
"Can't make directory for path '%s', it is a file.", fPart));
}
} catch (FileNotFoundException fnfe) {
}
fPart = fPart.getParent();
} while (fPart != null);
}
@Override
public FSDataInputStream open(Path path, int bufferSize) throws IOException {
final FileStatus fileStatus = getFileStatus(path);
if (fileStatus.isDirectory()) {
throw new FileNotFoundException("Can't open " + path +
" because it is a directory");
}
return new FSDataInputStream(new AliyunOSSInputStream(getConf(),
new SemaphoredDelegatingExecutor(View on GitHub (pinned to 2add963021)
Solutions
- Identify the offending ancestor from the message and delete or rename that file object
- Rework the path scheme so file names never double as directory prefixes
- After cleanup, re-run the job; mkdirs then creates the directory markers without conflict
Defensive patterns
Strategy: validation
Validate before calling
for (Path a = path.getParent(); a != null; a = a.getParent()) {
if (fs.exists(a) && fs.getFileStatus(a).isFile()) {
throw new IOException("Ancestor is a file: " + a);
}
}
fs.mkdirs(path); Try / catch
catch (FileAlreadyExistsException e) { /* message names the offending ancestor; delete/rename it then retry mkdirs */ throw e; } Prevention
- Pre-validate the ancestor chain of deep output paths once at job setup
- Avoid layouts where former leaf files become interior prefixes
When it happens
Trigger: Calling fs.mkdirs(deepPath) where an intermediate key exists as a file object — e.g., mkdirs(oss://bucket/a/b/c) while 'a' or 'a/b' is stored as a plain object; typically surfaced inside OutputCommitter/OutputFormat directory setup.
Common situations: Data layout evolution where a former leaf file became an interior path; keys written by non-Hadoop tools at conflicting prefixes; partial writes from a failed job leaving a file where a directory tree is expected.
Related errors
- Path is a file: {path}
- Credentials should not be null.
- Invalid credentials
- Stream closed.
- Failed to multipart upload to oss, abort it.
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/7fd51e648d03f5b5.
Report an issue: GitHub.