apache/hadoop · error · PathIOException

Can not delete root path

Error message

Can not delete root path

What it means

CosNFileSystem.delete refuses to delete the filesystem root (the bucket itself) unless it is empty. rejectRootDirectoryDelete returns harmlessly when the root is empty, but a non-empty root combined with recursive=false throws PathIOException('Can not delete root path'). The guard exists because one recursive call at the root would wipe every object in the bucket.

Source

Thrown at hadoop-cloud-storage-project/hadoop-cos/src/main/java/org/apache/hadoop/fs/cosn/CosNFileSystem.java:274

      LOG.debug("Creating a new file: [{}] in COS.", f);
    }

    Path absolutePath = makeAbsolute(f);
    String key = pathToKey(absolutePath);
    return new FSDataOutputStream(
        new CosNOutputStream(getConf(), store, key, blockSize,
            this.boundedIOThreadPool), statistics);
  }

  private boolean rejectRootDirectoryDelete(boolean isEmptyDir,
      boolean recursive) throws PathIOException {
    if (isEmptyDir) {
      return true;
    }
    if (recursive) {
      return false;
    } else {
      throw new PathIOException(this.bucket, "Can not delete root path");
    }
  }

  @Override
  public FSDataOutputStream createNonRecursive(Path f, FsPermission permission,
      EnumSet<CreateFlag> flags, int bufferSize, short replication,
      long blockSize, Progressable progress) throws IOException {
    Path parent = f.getParent();
    if (null != parent) {
      if (!getFileStatus(parent).isDirectory()) {
        throw new FileAlreadyExistsException("Not a directory: " + parent);
      }
    }

    return create(f, permission, flags.contains(CreateFlag.OVERWRITE),
        bufferSize, replication, blockSize, progress);
  }

View on GitHub (pinned to 2add963021)

Solutions

  1. Target the specific subdirectories or files to delete instead of the root.
  2. If wiping the bucket is intended, use fs.delete(root, true) (hadoop fs -rm -r) and understand it deletes every object.
  3. Fix the calling script so the delete path can never be the root: validate !path.isRoot() before delete.

Example fix

// before
fs.delete(new Path('/'), false); // PathIOException: Can not delete root path

// after
Path target = (base == null || base.isEmpty()) ? new Path('/data') : new Path(base);
if (!target.isRoot()) {
  fs.delete(target, true);
}
Defensive patterns

Strategy: validation

Validate before calling

Path p = base == null ? new Path('/') : new Path(base);
if (p.isRoot()) {
  // refuse, or expand into explicit children
  for (FileStatus st : fs.listStatus(p)) { fs.delete(st.getPath(), true); }
} else {
  fs.delete(p, recursive);
}

Try / catch

try {
  fs.delete(p, false);
} catch (PathIOException e) {
  if (p.isRoot()) { /* policy decision: enumerate children instead */ } else { throw e; }
}

Prevention

When it happens

Trigger: fs.delete(new Path('/'), false) on a bucket containing any object; hadoop fs -rm cosn://bucket/ (without -r) on a non-empty bucket; cleanup scripts whose path variable resolves to the root when empty.

Common situations: A 'base path' variable built from string concatenation that ends up empty and normalizes to the root; operating on the mount root of a cosn mount table; using -rm where -rmdir or an explicit child path was intended.

Related errors


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