apache/hadoop · error · IOException
Source '{srcFile}' exists but is a directory
Error message
Source '{srcFile}' exists but is a directory What it means
Guard clause of Storage.nativeCopyFileUnbuffered: srcFile exists but isDirectory() is true. The helper copies a single regular file with OS unbuffered IO; directories are rejected so NativeIO.copyFileUnbuffered never receives a directory handle.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/Storage.java:1336
* should be the same as the original
*
* @throws NullPointerException if source or destination is {@code null}
* @throws IOException if source or destination is invalid
* @throws IOException if an IO error occurs during copying
*/
public static void nativeCopyFileUnbuffered(File srcFile, File destFile,
boolean preserveFileDate) throws IOException {
if (srcFile == null) {
throw new NullPointerException("Source must not be null");
}
if (destFile == null) {
throw new NullPointerException("Destination must not be null");
}
if (srcFile.exists() == false) {
throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
}
if (srcFile.isDirectory()) {
throw new IOException("Source '" + srcFile + "' exists but is a directory");
}
if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) {
throw new IOException("Source '" + srcFile + "' and destination '" +
destFile + "' are the same");
}
File parentFile = destFile.getParentFile();
if (parentFile != null) {
if (!parentFile.mkdirs() && !parentFile.isDirectory()) {
throw new IOException("Destination '" + parentFile
+ "' directory cannot be created");
}
}
if (destFile.exists()) {
if (FileUtil.canWrite(destFile) == false) {
throw new IOException("Destination '" + destFile
+ "' exists but is read-only");
} else {
if (destFile.delete() == false) {View on GitHub (pinned to 2add963021)
Solutions
- Point the copy at the file inside the directory
- If a whole directory must be copied, walk its entries and copy each file (e.g. FileUtil.copy) rather than this single-file API
Example fix
// before
Storage.nativeCopyFileUnbuffered(new File("/nn/current"), dst, true);
// after
Storage.nativeCopyFileUnbuffered(new File("/nn/current/fsimage_0001"), dst, true); Defensive patterns
Strategy: validation
Validate before calling
if (srcFile != null && srcFile.isDirectory()) {
throw new IOException("expected a file but got directory: " + srcFile.getAbsolutePath());
} Type guard
static boolean isFileNotDirectory(File f) {
return f != null && f.isFile() && !f.isDirectory();
} Prevention
- Use File.isFile() (not exists()) when validating copy sources
- Keep directory-level and file-level config settings clearly named to avoid mix-ups
When it happens
Trigger: The source path points at a directory (e.g. the checkpoint directory instead of the fsimage inside it); a glob or config value expanded to a directory; a path where the expected file was replaced by a same-named directory.
Common situations: Configuring a copy source with a directory-level setting instead of the file; tests with fixture layout mismatches; scripts that pass dirname instead of a file path.
Related errors
- Source '{srcFile}' does not exist
- Source '{srcFile}' and destination '{destFile}' are the same
- Destination '{parentFile}' directory cannot be created
- Destination '{destFile}' exists but is read-only
- Invalid path: {location}: directory does not exist
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/f747a69af1144248.
Report an issue: GitHub.