{"record":{"id":"11698a8b91499b60","repo":"apache/hadoop","slug":"xattr-does-not-exist-the-create-flag-must-be","errorCode":null,"errorMessage":"XAttr: {} does not exist. The CREATE flag must be specified.","messagePattern":"XAttr: (.+?) does not exist\\. The CREATE 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":765,"sourceCode":"      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":747,"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#L747-L771","documentation":"The inverse branch of the same setXAttr validation: the attribute does not exist and the caller did not pass XAttrSetFlag.CREATE, so the write is rejected. Without CREATE, setting a brand-new name would create metadata the caller did not assert intent to create.","triggerScenarios":"fs.setXAttr(path, name, value, EnumSet.of(XAttrSetFlag.REPLACE)) when no tag with that name exists (e.g. it was removed, or a typo in the name).","commonSituations":"Update-after-delete flows where the tag was cleared between runs; name typos ('user.ownr') making REPLACE target nothing; tags removed out-of-band in the TOS console.","solutions":["Include CREATE whenever the attribute may legitimately not exist yet: EnumSet.of(CREATE, REPLACE)","Verify the name spelling against listXAttrs(path) before a REPLACE-only write","Re-create the tag explicitly with CREATE if the delete was unintentional"],"exampleFix":"// before\nfs.setXAttr(path, \"user.owner\", value, EnumSet.of(XAttrSetFlag.REPLACE)); // absent -> 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);\nif (!exists) {\n  fs.setXAttr(path, name, value, EnumSet.of(XAttrSetFlag.CREATE));\n} else {\n  fs.setXAttr(path, name, value, EnumSet.of(XAttrSetFlag.REPLACE));\n}","typeGuard":null,"tryCatchPattern":"try { fs.setXAttr(path, name, value, EnumSet.of(REPLACE)); }\ncatch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"CREATE flag\")) {\n    fs.setXAttr(path, name, value, EnumSet.of(CREATE, REPLACE));\n  } else throw e;\n}","preventionTips":["Upsert with CREATE|REPLACE unless create-only semantics are required","Verify tag name spelling against listXAttrs before update-only writes","Expect absent tags after out-of-band deletions and re-create them"],"tags":["xattr","flag-validation","create-flag","object-tags","tos"],"backgroundTag":"xattr-not-found","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}