{"record":{"id":"6d578eb0c6b3695f","repo":"apache/hadoop","slug":"xattr-already-exists-the-replace-flag-must-be","errorCode":null,"errorMessage":"XAttr: {} already exists. The REPLACE flag must be specified.","messagePattern":"XAttr: (.+?) already exists\\. The REPLACE flag must be specified\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/RawFileSystem.java","lineNumber":760,"sourceCode":"\n  @Override\n  public void removeXAttr(Path path, String name) throws IOException {\n    if (getFileStatus(path).isFile()) {\n      Path qualifiedPath = path.makeQualified(uri, workingDir);\n      String key = ObjectUtils.pathToKey(qualifiedPath);\n\n      Map<String, String> existedTags = storage.getTags(key);\n      if (existedTags.remove(name) != null) {\n        storage.putTags(key, existedTags);\n      }\n    }\n  }\n\n  private void validateXAttrFlag(String xAttrName, boolean xAttrExists, EnumSet<XAttrSetFlag> flag)\n      throws IOException {\n    if (xAttrExists) {\n      if (!flag.contains(REPLACE)) {\n        throw new IOException(\"XAttr: \" + xAttrName + \" already exists. The REPLACE flag must be\"\n            + \" specified.\");\n      }\n    } else {\n      if (!flag.contains(CREATE)) {\n        throw new IOException(\"XAttr: \" + xAttrName + \" does not exist. The CREATE flag must be\"\n            + \" specified.\");\n      }\n    }\n  }\n}\n","sourceCodeStart":742,"sourceCodeEnd":771,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/RawFileSystem.java#L742-L771","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nfs.setXAttr(path, \"user.owner\", value, EnumSet.of(XAttrSetFlag.CREATE)); // exists -> IOException\n\n// after\nfs.setXAttr(path, \"user.owner\", value, EnumSet.of(XAttrSetFlag.CREATE, XAttrSetFlag.REPLACE));","handlingStrategy":"validation","validationCode":"boolean exists = fs.listXAttrs(path).contains(name);\nEnumSet<XAttrSetFlag> flags = exists\n    ? EnumSet.of(XAttrSetFlag.REPLACE)\n    : EnumSet.of(XAttrSetFlag.CREATE);\nfs.setXAttr(path, name, value, flags);","typeGuard":null,"tryCatchPattern":"try { fs.setXAttr(path, name, value, EnumSet.of(CREATE)); }\ncatch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"REPLACE flag\")) {\n    fs.setXAttr(path, name, value, EnumSet.of(CREATE, REPLACE)); // upsert retry\n  } else throw e;\n}","preventionTips":["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"],"tags":["xattr","flag-validation","replace-flag","object-tags","tos"],"backgroundTag":"xattr-flag-conflict","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}