apache/hadoop · error · IOException
XAttr: {} already exists. The REPLACE flag must be specified
Error message
XAttr: {} already exists. The REPLACE flag must be specified. What it means
setXAttr flag validation throws IOException when the attribute already exists and the caller did not pass XAttrSetFlag.REPLACE. This mirrors HDFS xattr semantics: setting an existing attribute requires explicit REPLACE, preventing accidental overwrites of object-tag-backed metadata.
Source
Thrown at hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/RawFileSystem.java:760
@Override
public void removeXAttr(Path path, String name) throws IOException {
if (getFileStatus(path).isFile()) {
Path qualifiedPath = path.makeQualified(uri, workingDir);
String key = ObjectUtils.pathToKey(qualifiedPath);
Map<String, String> existedTags = storage.getTags(key);
if (existedTags.remove(name) != null) {
storage.putTags(key, existedTags);
}
}
}
private void validateXAttrFlag(String xAttrName, boolean xAttrExists, EnumSet<XAttrSetFlag> flag)
throws IOException {
if (xAttrExists) {
if (!flag.contains(REPLACE)) {
throw new IOException("XAttr: " + xAttrName + " already exists. The REPLACE flag must be"
+ " specified.");
}
} else {
if (!flag.contains(CREATE)) {
throw new IOException("XAttr: " + xAttrName + " does not exist. The CREATE flag must be"
+ " specified.");
}
}
}
}
View on GitHub (pinned to 2add963021)
Solutions
- Pass both flags for upsert semantics: EnumSet.of(CREATE, REPLACE)
- Delete the tag first via removeXAttr if you need set-if-absent semantics with your own conflict handling
- Check existence first: listXAttrs(path).contains(name), then choose CREATE or REPLACE accordingly
Example fix
// before fs.setXAttr(path, "user.owner", value, EnumSet.of(XAttrSetFlag.CREATE)); // exists -> IOException // after fs.setXAttr(path, "user.owner", value, EnumSet.of(XAttrSetFlag.CREATE, XAttrSetFlag.REPLACE));
Defensive patterns
Strategy: validation
Validate before calling
boolean exists = fs.listXAttrs(path).contains(name);
EnumSet<XAttrSetFlag> flags = exists
? EnumSet.of(XAttrSetFlag.REPLACE)
: EnumSet.of(XAttrSetFlag.CREATE);
fs.setXAttr(path, name, value, flags); Try / catch
try { fs.setXAttr(path, name, value, EnumSet.of(CREATE)); }
catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("REPLACE flag")) {
fs.setXAttr(path, name, value, EnumSet.of(CREATE, REPLACE)); // upsert retry
} else throw e;
} Prevention
- Use EnumSet.of(CREATE, REPLACE) for idempotent annotation writes
- Make jobs re-runnable by designing setXAttr calls as upserts
- Check listXAttrs before REPLACE-sensitive logic
When it happens
Trigger: fs.setXAttr(path, name, value, EnumSet.of(XAttrSetFlag.CREATE)) (or an EnumSet lacking REPLACE) when a tag with that name already exists on the object.
Common situations: Re-running jobs that annotate outputs (second run hits the tags it created in the first); idempotent metadata stamping without REPLACE; concurrent annotators writing the same tag name.
Related errors
- XAttr: {} does not exist. The CREATE flag must be specified.
- Attribute with name {} is not found.
- Attributes with name {} are not found.
- Can't open %s because it is a directory
- {} is a directory
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/6d578eb0c6b3695f.
Report an issue: GitHub.