apache/hadoop · error · AccessControlException

Cannot Rename within internal dirs of mount table: dest={} i

Error message

Cannot Rename within internal dirs of mount table: dest={} is readOnly

What it means

The destination half of ViewFs.renameInternal: when dst resolves (with resolveLastComponent=false) to an internal dir and no root fallback link is configured, there is no target FileSystem to receive the rename, so it throws AccessControlException("Cannot Rename within internal dirs of mount table: dest=<dst> is readOnly"). With a fallback configured, the code instead tries resolving dst with the last component to allow renames that land under the fallback (see comment in source).

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFs.java:603

          fsState.resolve(getUriPath(src), true);
      if (resSrcWithLastComp.isInternalDir() || resSrcWithLastComp
          .isLastInternalDirLink()) {
        throw new AccessControlException(
            "Cannot Rename within internal dirs of mount table: src=" + src
                + " is readOnly");
      } else {
        // This is fallback and let's set the src fs with this fallback
        resSrc = resSrcWithLastComp;
      }
    }

    InodeTree.ResolveResult<AbstractFileSystem> resDst =
        fsState.resolve(getUriPath(dst), false);

    if (resDst.isInternalDir()) {
      if (fsState.getRootFallbackLink() == null) {
        // If fallback is null, we can't rename to dst.
        throw new AccessControlException(
            "Cannot Rename within internal dirs of mount table: dest=" + dst
                + " is readOnly");
      }
      // if the fallback exist, we may have chance to rename to fallback path
      // where dst parent is matching to internalDir.
      InodeTree.ResolveResult<AbstractFileSystem> resDstWithLastComp =
          fsState.resolve(getUriPath(dst), true);
      if (resDstWithLastComp.isInternalDir()) {
        // We need to get fallback here. If matching fallback path not exist, it
        // will fail later. This is a very special case: Even though we are on
        // internal directory, we should allow to rename, so that src files will
        // moved under matching fallback dir.
        resDst = new InodeTree.ResolveResult<AbstractFileSystem>(
            InodeTree.ResultKind.INTERNAL_DIR,
            fsState.getRootFallbackLink().getTargetFileSystem(), "/",
            new Path(resDstWithLastComp.resolvedPath), false);
      } else {
        // The link resolved to some target fs or fallback fs.

View on GitHub (pinned to 2add963021)

Solutions

  1. Configure fs.viewfs.mounttable.<n>.linkFallback so dest falls through to a real cluster
  2. Add an explicit mount link for the destination parent (fs.viewfs.mounttable.<n>.link./archive)
  3. Rename to a concrete path inside an existing mount point

Example fix

<!-- before: rename to /archive (virtual) throws -->

<!-- after (core-site.xml) -->
<property><name>fs.viewfs.mounttable.c1.link./archive</name>
  <value>hdfs://nnArchive:8020/archive</value></property>
Defensive patterns

Strategy: try-catch

Validate before calling

static boolean renameDstOk(ViewFileSystem vfs, Path dst) {
  String s = dst.toUri().getPath();
  if (s.equals("/")) return false;
  return vfs.getMountPoints().stream()
      .map(mp -> mp.getMountedOnPath().toUri().getPath())
      .anyMatch(m -> s.startsWith(m.endsWith("/") ? m : m + "/")); // false -> needs linkFallback or a new link
}

Try / catch

try {
  fc.rename(src, dst, Rename.NONE);
} catch (AccessControlException ace) {
  if (ace.getMessage().contains("dest=") && ace.getMessage().contains("readOnly")) {
    // dest resolves to internal dir without fallback: add linkFallback or link the dest parent
  }
}

Prevention

When it happens

Trigger: FileContext.rename(src, viewfs:///archive, ...) where /archive is a virtual container with links only beneath it and linkFallback is unset; tools archiving data to federated parent dirs that the mount table does not mount directly.

Common situations: Archive/rotation jobs writing to directory levels that exist only virtually; same federation clients as errors 993/994 — the src side was fixed via fallback but dst now fails, or vice versa.

Related errors


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