apache/hadoop · error · PathIsDirectoryException
dst.toString()
Error message
dst.toString()
What it means
checkDest() throws PathIsDirectoryException(dst.toString()) when the resolved destination path on dstFS already exists as a directory and overwrite is false and there is no source name to join onto it (srcName == null). PathIsDirectoryException extends IOException, so it surfaces as a normal IO error from FileUtil.copy. The message body is just the destination path string. It means 'you asked to write a file where a directory stands'.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java:621
return true;
}
}
private static Path checkDest(String srcName, FileSystem dstFS, Path dst,
boolean overwrite) throws IOException {
FileStatus sdst;
try {
sdst = dstFS.getFileStatus(dst);
} catch (FileNotFoundException e) {
sdst = null;
}
if (null != sdst) {
if (sdst.isDirectory()) {
if (null == srcName) {
if (overwrite) {
return dst;
}
throw new PathIsDirectoryException(dst.toString());
}
return checkDest(null, dstFS, new Path(dst, srcName), overwrite);
} else if (!overwrite) {
throw new PathExistsException(dst.toString(),
"Target " + dst + " already exists");
}
}
return dst;
}
public static boolean isRegularFile(File file) {
return isRegularFile(file, true);
}
/**
* Check if the file is regular.
* @param file The file being checked.
* @param allowLinks Whether to allow matching links.View on GitHub (pinned to 2add963021)
Solutions
- Point the destination at a file path that does not collide with an existing directory (dst + '/filename')
- Delete or rename the conflicting directory on dstFS before copying
- Catch PathIsDirectoryException and either fail with a clear message or route to a new destination
- Use FileSystem.copyFromLocalFile(delSrc, overwrite, src, dst) when you want overwrite semantics instead of the hard-coded overwrite=false in this copy() overload
Example fix
// before
FileUtil.copy(new File("data.txt"), fs, new Path("/out/data.txt"), false, conf);
// throws PathIsDirectoryException when /out/data.txt is a directory
// after
Path dst = new Path("/out/data.txt");
FileStatus st = fs.exists(dst) ? fs.getFileStatus(dst) : null;
if (st != null && st.isDirectory()) {
throw new IOException("Refusing to overwrite directory " + dst);
}
FileUtil.copy(new File("data.txt"), fs, dst, false, conf); Defensive patterns
Strategy: validation
Validate before calling
Path dst = new Path("/out/data.txt");
if (dstFS.exists(dst) && dstFS.getFileStatus(dst).isDirectory()) {
throw new IOException("Destination " + dst + " is a directory; refusing to copy file onto it");
}
FileUtil.copy(src, dstFS, dst, false, conf); Try / catch
try {
FileUtil.copy(src, dstFS, dst, false, conf);
} catch (PathIsDirectoryException e) {
// dst resolves to an existing directory; pick a file-level destination
dst = new Path(dst, src.getName());
FileUtil.copy(src, dstFS, dst, false, conf);
} Prevention
- Always build file destinations as dstDir + '/' + fileName, never the bare directory
- Before copy, assert !dstFS.exists(dst) || !dstFS.getFileStatus(dst).isDirectory()
- Prefer copyFromLocalFile(delSrc, overwrite, ...) when overwrite semantics are wanted
When it happens
Trigger: FileUtil.copy(File src, FileSystem dstFS, Path dst, false, conf) where dst (or dst/srcName via the recursive checkDest(null, ...) call) resolves to an existing directory; checkDest recursing into new Path(dst, srcName) that collides with a pre-existing subdirectory of the same name.
Common situations: Uploading a file named 'conf' into an HDFS dir that already contains a directory 'conf'; CI jobs re-running a put without -f semantics; passing an HDFS directory path as the file destination.
Related errors
- Target " + dst + " already exists
- src.toString() + ": No such file or directory"
- No attribute for {}
- No such file or directory
- Too many matches
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/89ccf6ccbe3972a7.
Report an issue: GitHub.