apache/hadoop · error · IOException

Har: delete not allowed

Error message

Har: delete not allowed

What it means

delete is rejected with 'Har: delete not allowed': removing a member would mean editing the immutable index and part files. Nothing inside a har can be deleted; only the whole .har can be removed as a unit on the underlying filesystem.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/HarFileSystem.java:777

  @Override
  public FSDataOutputStream append(Path f) throws IOException {
    throw new IOException("Har: append not allowed");
  }

  /**
   * Not implemented.
   */
  @Override
  public boolean truncate(Path f, long newLength) throws IOException {
    throw new IOException("Har: truncate not allowed");
  }

  /**
   * Not implemented.
   */
  @Override
  public boolean delete(Path f, boolean recursive) throws IOException { 
    throw new IOException("Har: delete not allowed");
  }

  /**
   * liststatus returns the children of a directory 
   * after looking up the index files.
   */
  @Override
  public FileStatus[] listStatus(Path f) throws IOException {
    //need to see if the file is an index in file
    //get the filestatus of the archive directory
    // we will create fake filestatuses to return
    // to the client
    List<FileStatus> statuses = new ArrayList<FileStatus>();
    Path tmpPath = makeQualified(f);
    Path harPath = getPathInHar(tmpPath);
    HarStatus hstatus = metadata.archive.get(harPath);
    if (hstatus == null) {
      throw new FileNotFoundException("File " + f + " not found in " + archivePath);

View on GitHub (pinned to 2add963021)

Solutions

  1. If the entire archive is disposable, delete the .har directory on the underlying filesystem: hdfs.delete(new Path("/a/data.har"), true)
  2. Guard cleanup code to skip read-only schemes (check scheme equals 'har')
  3. Rebuild the archive without the unwanted files if selective removal is required

Example fix

// before
if (fs.exists(p)) { fs.delete(p, true); } // p is har://...: throws

// after
if ("har".equals(p.toUri().getScheme())) {
  hdfs.delete(new Path("hdfs://nn:8020/a/data.har"), true); // drop whole archive
} else if (fs.exists(p)) {
  fs.delete(p, true);
}
Defensive patterns

Strategy: validation

Validate before calling

if ("har".equals(p.toUri().getScheme())) {
  // nothing inside a har can be deleted; drop the whole archive on the underlying fs if disposable
  // hdfs.delete(underlyingArchivePath, true);
  return;
}
fs.delete(p, recursive);

Try / catch

try {
  fs.delete(p, true);
} catch (IOException e) {
  if (e.getMessage() != null && e.getMessage().contains("not allowed")) {
    // read-only destination: skip member-level cleanup
  }
  throw e;
}

Prevention

When it happens

Trigger: fs.delete(harPath, recursive) on any har:// path — the classic source is cleanup logic like `if (fs.exists(p)) fs.delete(p, true)`, overwrite handling, and job-abort cleanup that sweeps output locations including har:// ones.

Common situations: Idempotent re-run scripts that clean destinations first; task/job failure recovery deleting scratch paths; retention jobs that walk mixed HDFS/har trees.

Related errors


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