{"record":{"id":"3fb53e21a8b6187c","repo":"apache/hadoop","slug":"har-delete-not-allowed","errorCode":null,"errorMessage":"Har: delete not allowed","messagePattern":"Har: delete not allowed","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/HarFileSystem.java","lineNumber":777,"sourceCode":"  @Override\n  public FSDataOutputStream append(Path f) throws IOException {\n    throw new IOException(\"Har: append not allowed\");\n  }\n\n  /**\n   * Not implemented.\n   */\n  @Override\n  public boolean truncate(Path f, long newLength) throws IOException {\n    throw new IOException(\"Har: truncate not allowed\");\n  }\n\n  /**\n   * Not implemented.\n   */\n  @Override\n  public boolean delete(Path f, boolean recursive) throws IOException { \n    throw new IOException(\"Har: delete not allowed\");\n  }\n\n  /**\n   * liststatus returns the children of a directory \n   * after looking up the index files.\n   */\n  @Override\n  public FileStatus[] listStatus(Path f) throws IOException {\n    //need to see if the file is an index in file\n    //get the filestatus of the archive directory\n    // we will create fake filestatuses to return\n    // to the client\n    List<FileStatus> statuses = new ArrayList<FileStatus>();\n    Path tmpPath = makeQualified(f);\n    Path harPath = getPathInHar(tmpPath);\n    HarStatus hstatus = metadata.archive.get(harPath);\n    if (hstatus == null) {\n      throw new FileNotFoundException(\"File \" + f + \" not found in \" + archivePath);","sourceCodeStart":759,"sourceCodeEnd":795,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/HarFileSystem.java#L759-L795","documentation":"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.","triggerScenarios":"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.","commonSituations":"Idempotent re-run scripts that clean destinations first; task/job failure recovery deleting scratch paths; retention jobs that walk mixed HDFS/har trees.","solutions":["If the entire archive is disposable, delete the .har directory on the underlying filesystem: hdfs.delete(new Path(\"/a/data.har\"), true)","Guard cleanup code to skip read-only schemes (check scheme equals 'har')","Rebuild the archive without the unwanted files if selective removal is required"],"exampleFix":"// before\nif (fs.exists(p)) { fs.delete(p, true); } // p is har://...: throws\n\n// after\nif (\"har\".equals(p.toUri().getScheme())) {\n  hdfs.delete(new Path(\"hdfs://nn:8020/a/data.har\"), true); // drop whole archive\n} else if (fs.exists(p)) {\n  fs.delete(p, true);\n}","handlingStrategy":"validation","validationCode":"if (\"har\".equals(p.toUri().getScheme())) {\n  // nothing inside a har can be deleted; drop the whole archive on the underlying fs if disposable\n  // hdfs.delete(underlyingArchivePath, true);\n  return;\n}\nfs.delete(p, recursive);","typeGuard":null,"tryCatchPattern":"try {\n  fs.delete(p, true);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"not allowed\")) {\n    // read-only destination: skip member-level cleanup\n  }\n  throw e;\n}","preventionTips":["Make idempotent cleanup scripts scheme-aware before calling exists/delete","Remember delete granularity: whole .har on the underlying fs, never individual members","Don't point job-abort cleanup at paths that may live under har://"],"tags":["hadoop","har-filesystem","read-only","delete","cleanup"],"backgroundTag":"read-only-filesystem-write","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}