apache/hadoop · error · IOException
Cannot append to a diretory (=" + f + " )
Error message
Cannot append to a diretory (=" + f + " )
What it means
RawLocalFileSystem.append(Path, int, Progressable) first calls getFileStatus and throws a plain IOException when the target is a directory, because appending bytes to a directory is meaningless on a local filesystem. Note the historic typo 'diretory' in the message itself; match on exception type and prefix, not the exact spelling, if you must string-match.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/RawLocalFileSystem.java:622
case StreamCapabilities.IOSTATISTICS_CONTEXT:
return true;
default:
return StoreImplementationUtils.isProbeForSyncable(capability);
}
}
@Override
public IOStatistics getIOStatistics() {
return ioStatistics;
}
}
@Override
public FSDataOutputStream append(Path f, int bufferSize,
Progressable progress) throws IOException {
FileStatus status = getFileStatus(f);
if (status.isDirectory()) {
throw new IOException("Cannot append to a diretory (=" + f + " )");
}
return new FSDataOutputStream(new BufferedOutputStream(
createOutputStreamWithMode(f, true, null), bufferSize), statistics,
status.getLen());
}
@Override
public FSDataOutputStream create(Path f, boolean overwrite, int bufferSize,
short replication, long blockSize, Progressable progress)
throws IOException {
return create(f, overwrite, true, bufferSize, replication, blockSize,
progress, null);
}
private FSDataOutputStream create(Path f, boolean overwrite,
boolean createParent, int bufferSize, short replication, long blockSize,
Progressable progress, FsPermission permission) throws IOException {
if (exists(f) && !overwrite) {View on GitHub (pinned to 2add963021)
Solutions
- Append to a file inside the directory: append(new Path(dir, "part-00000")) rather than the directory itself.
- Check first: if (fs.getFileStatus(p).isDirectory()) { throw or pick a file path; } before calling append.
- If you expected a file at that path, inspect the directory for stray mkdirs calls or a previous run that created a directory there, and delete/rename it.
- Use fs.exists(p) && fs.getFileStatus(p).isFile() as a precondition when the path type is not guaranteed.
Example fix
// before
FileSystem fs = FileSystem.getLocal(conf);
FSDataOutputStream out = fs.append(new Path("/jobs/out")); // /jobs/out is a dir
// after
Path outDir = new Path("/jobs/out");
Path partFile = new Path(outDir, "part-00000");
FSDataOutputStream out = fs.append(partFile); Defensive patterns
Strategy: validation
Validate before calling
public static FSDataOutputStream appendFile(FileSystem fs, Path p) throws IOException {
FileStatus st = fs.getFileStatus(p);
if (st.isDirectory()) {
throw new IllegalArgumentException(p + " is a directory; append to a file inside it");
}
return fs.append(p);
} Try / catch
try {
return fs.append(p);
} catch (IOException e) {
if (fs.exists(p) && fs.getFileStatus(p).isDirectory()) {
throw new IllegalArgumentException(p + " is a directory", e);
}
throw e;
} Prevention
- Construct append targets as dir + explicit filename, never the directory itself.
- Stat and assert isFile() before append when the path type is external input.
- Watch for trailing slashes and symlinks that normalize to directories.
When it happens
Trigger: Calling fs.append(path) on a local Path that resolves to a directory (e.g. the job output directory instead of a part-file inside it), appending to a path that a prior mkdirs created, or a trailing-slash path that normalizes to a directory.
Common situations: Building an output path like /out instead of /out/part-00000, reusing a MapReduce output directory as an append target, configuration pointing fs.defaultFS at file:/// with a directory-valued path, or a symlink that resolves to a directory.
Related errors
- Cannot truncate a directory (=" + f + ")
- Append is not supported by ChecksumFileSystem
- Directory {} is not empty.
- new destination is an existed directory
- Can't open %s because it is a directory
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/0769c8e5ec00d548.
Report an issue: GitHub.