{"record":{"id":"87dffecfc96df0d4","repo":"apache/hadoop","slug":"cannot-delete-internal-mount-table-directory","errorCode":null,"errorMessage":"Cannot delete internal mount table directory: {}","messagePattern":"Cannot delete internal mount table directory: (.+?)","errorType":"exception","errorClass":"AccessControlException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFs.java","lineNumber":374,"sourceCode":"        throw e;\n      }\n    }\n    assert(res.remainingPath != null);\n    return res.targetFileSystem.createInternal(res.remainingPath, flag,\n        absolutePermission, bufferSize, replication,\n        blockSize, progress, checksumOpt,\n        createParent);\n  }\n\n  @Override\n  public boolean delete(final Path f, final boolean recursive)\n      throws AccessControlException, FileNotFoundException,\n      UnresolvedLinkException, IOException {\n    InodeTree.ResolveResult<AbstractFileSystem> res =\n      fsState.resolve(getUriPath(f), true);\n    // If internal dir or target is a mount link (ie remainingPath is Slash)\n    if (res.isInternalDir() || res.remainingPath == InodeTree.SlashPath) {\n      throw new AccessControlException(\n          \"Cannot delete internal mount table directory: \" + f);\n    }\n    return res.targetFileSystem.delete(res.remainingPath, recursive);\n  }\n\n  @Override\n  public BlockLocation[] getFileBlockLocations(final Path f, final long start,\n      final long len) throws AccessControlException, FileNotFoundException,\n      UnresolvedLinkException, IOException {\n    InodeTree.ResolveResult<AbstractFileSystem> res =\n      fsState.resolve(getUriPath(f), true);\n    return\n      res.targetFileSystem.getFileBlockLocations(res.remainingPath, start, len);\n  }\n\n  @Override\n  public FileChecksum getFileChecksum(final Path f)\n      throws AccessControlException, FileNotFoundException,","sourceCodeStart":356,"sourceCodeEnd":392,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFs.java#L356-L392","documentation":"ViewFs.delete resolves the path and refuses deletion when the result is an internal mount-table directory (res.isInternalDir()) or the remaining path is the mount link itself (remainingPath == SlashPath), throwing AccessControlException(\"Cannot delete internal mount table directory: <path>\"). The mount table's structural nodes are read-only by design — no fallback link is consulted on this path.","triggerScenarios":"FileContext delete(true) on viewfs:/// (root) or on /user when only /user/alice is mounted; recursive deletes that start at a virtual container directory rather than inside a mount point.","commonSituations":"Cleanup jobs (`hadoop fs -rm -r viewfs:///...`) written before federation assuming plain HDFS; CI/EMR bootstrap scripts wiping scratch roots that are virtual dirs in the mount table.","solutions":["Delete concrete children inside mount points (e.g. viewfs:///user/alice/tmp) instead of the virtual ancestor","Enumerate mount points via the viewfs API and delete within each mounted filesystem","Catch AccessControlException and report 'read-only mount table node' instead of retrying","Have admins remove the mount entry itself if the goal is to unmount"],"exampleFix":"// before\nfc.delete(new Path(\"viewfs:///data\"), true); // /data is a virtual dir -> throws\n\n// after\nfor (MountPoint mp : ((ViewFs) fc.getDefaultFileSystem()).getMountPoints()) { /* delete inside mp */ }\n// or target a concrete mounted child:\nfc.delete(new Path(\"viewfs:///data/ds1/old\"), true);","handlingStrategy":"try-catch","validationCode":"static boolean deletable(ViewFs vfs, Path p) throws IOException {\n  String s = p.toUri().getPath();\n  if (s.equals(\"/\")) return false;\n  return vfs.getMountPoints().stream()\n      .map(mp -> mp.getMountedOnPath().toUri().getPath())\n      .anyMatch(m -> s.equals(m) || s.startsWith(m + \"/\"));\n}","typeGuard":null,"tryCatchPattern":"try {\n  deleted = fc.delete(p, true);\n} catch (AccessControlException e) {\n  // internal mount-table dir: not deletable via viewfs; delete inside mount points\n}","preventionTips":["Cleanup jobs should derive targets from getMountPoints(), not from namespace roots","Never expose `rm -r viewfs:///` in shared scripts"],"tags":["viewfs","mount-table","access-control","delete","hadoop-common"],"backgroundTag":"viewfs-internal-dir-protected","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}