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

  1. Pass both flags for upsert semantics: EnumSet.of(CREATE, REPLACE)
  2. Delete the tag first via removeXAttr if you need set-if-absent semantics with your own conflict handling
  3. 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

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


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