apache/hadoop · error · IOException
Can only set 'security.hdfs.unreadable.by.superuser' on a fi
Error message
Can only set 'security.hdfs.unreadable.by.superuser' on a file.
What it means
The unreadable-by-superuser marker is a per-file security property: it hides file data from the superuser, a notion defined only for file content. setINodeXAttrs throws IOException when the attribute is applied to a non-file inode such as a directory.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirXAttrOp.java:306
PBHelperClient.convert(ezProto.getSuite()),
PBHelperClient.convert(ezProto.getCryptoProtocolVersion()),
ezProto.getKeyName());
if (ezProto.hasReencryptionProto()) {
ReencryptionInfoProto reProto = ezProto.getReencryptionProto();
fsd.ezManager.getReencryptionStatus()
.updateZoneStatus(inode.getId(), iip.getPath(), reProto);
}
}
// Add inode id to movement queue if xattrs contain satisfy xattr.
if (XATTR_SATISFY_STORAGE_POLICY.equals(xaName)) {
FSDirSatisfyStoragePolicyOp.unprotectedSatisfyStoragePolicy(inode, fsd);
continue;
}
if (!isFile && SECURITY_XATTR_UNREADABLE_BY_SUPERUSER.equals(xaName)) {
throw new IOException("Can only set '" +
SECURITY_XATTR_UNREADABLE_BY_SUPERUSER + "' on a file.");
}
if (xaName.equals(XATTR_SNAPSHOT_DELETED) && !(inode.isDirectory() &&
inode.getParent().isSnapshottable())) {
throw new IOException("Can only set '" +
XATTR_SNAPSHOT_DELETED + "' on a snapshot root.");
}
}
XAttrStorage.updateINodeXAttrs(inode, newXAttrs, iip.getLatestSnapshotId());
return inode;
}
static List<XAttr> setINodeXAttrs(
FSDirectory fsd, final List<XAttr> existingXAttrs,
final List<XAttr> toSet, final EnumSet<XAttrSetFlag> flag)
throws IOException {View on GitHub (pinned to 2add963021)
Solutions
- Apply only to files: guard with fs.getFileStatus(path).isFile()
- For directory trees, walk contained files (listFiles with recursion) and tag each file, skipping directories
- If a bulk walk cannot pre-filter, catch and ignore this IOException for directory entries
Example fix
// before: blanket apply across a tree
fs.setXAttr(dirPath, "security.hdfs.unreadable.by.superuser", new byte[0]);
// after: files only
RemoteIterator<LocatedFileStatus> it = fs.listFiles(root, true);
while (it.hasNext()) {
fs.setXAttr(it.next().getPath(),
"security.hdfs.unreadable.by.superuser", new byte[0]);
} Defensive patterns
Strategy: validation
Validate before calling
if (fs.getFileStatus(path).isFile()) {
fs.setXAttr(path, "security.hdfs.unreadable.by.superuser", new byte[0]);
} // directories skipped by design Type guard
static boolean isRegularFile(FileSystem fs, Path p) throws IOException {
return fs.exists(p) && fs.getFileStatus(p).isFile();
} Try / catch
try {
fs.setXAttr(path, "security.hdfs.unreadable.by.superuser", new byte[0]);
} catch (IOException e) {
if (!fs.getFileStatus(path).isFile()) {
// directory entry in a recursive walk: ignore
} else { throw e; }
} Prevention
- Apply per-file security markers only after an isFile() check
- In recursive walks, skip directories when tagging
- Test privacy-tagging tools against mixed file/dir trees
When it happens
Trigger: setXAttr(path, "security.hdfs.unreadable.by.superuser", value) where path resolves to a directory, typically during a recursive walk that applies the marker to a whole tree including its directories.
Common situations: Recursive privacy tagging over directory trees; tools built for file paths pointed at mount roots; backup scripts reapplying captured xattrs verbatim.
Related errors
- The xattr 'security.hdfs.unreadable.by.superuser' can not be
- {} doesn't support setXAttr
- {} doesn't support getXAttr
- {} doesn't support getXAttrs
- '{}' copy from '/.reserved/raw' to non '/.reserved/raw'. Eit
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/dbb95c7d585f13b3.
Report an issue: GitHub.