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

  1. Append to a file inside the directory: append(new Path(dir, "part-00000")) rather than the directory itself.
  2. Check first: if (fs.getFileStatus(p).isDirectory()) { throw or pick a file path; } before calling append.
  3. 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.
  4. 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

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


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/0769c8e5ec00d548. Report an issue: GitHub.