apache/hadoop · error · IOException

XAttr: {xAttrName} already exists. The REPLACE flag must be

Error message

XAttr: {xAttrName} already exists. The REPLACE flag must be specified.

What it means

XAttrSetFlag.validate throws this IOException in POSIX-setxattr style: the named extended attribute already exists on the target, but the flag set does not include REPLACE, so overwriting is not authorized. The attribute name in the message is the fully qualified name (user.*, trusted.*, etc.).

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/XAttrSetFlag.java:61

  private final short flag;

  private XAttrSetFlag(short flag) {
    this.flag = flag;
  }

  short getFlag() {
    return flag;
  }

  public static void validate(String xAttrName, boolean xAttrExists,
      EnumSet<XAttrSetFlag> flag) throws IOException {
    if (flag == null || flag.isEmpty()) {
      throw new HadoopIllegalArgumentException("A flag must be specified.");
    }

    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. Use EnumSet.of(CREATE, REPLACE) when either state is acceptable (upsert)
  2. Check existence first with fs.getXAttr(path, name) != null and pick CREATE vs REPLACE (still subject to races)
  3. removeXAttr(path, name) before setting with CREATE
  4. Catch the IOException and retry with REPLACE if the attribute was created concurrently

Example fix

// before
fs.setXAttr(path, "user.tag", value, EnumSet.of(XAttrSetFlag.CREATE));
// IOException: XAttr user.tag already exists...

// after
fs.setXAttr(path, "user.tag", value,
    EnumSet.of(XAttrSetFlag.CREATE, XAttrSetFlag.REPLACE));
Defensive patterns

Strategy: fallback

Validate before calling

byte[] existing = fs.getXAttr(path, name);
EnumSet<XAttrSetFlag> flags = (existing != null)
    ? EnumSet.of(XAttrSetFlag.REPLACE)
    : EnumSet.of(XAttrSetFlag.CREATE);
fs.setXAttr(path, name, value, flags); // still racy between get and set

Try / catch

try {
  fs.setXAttr(path, name, value, EnumSet.of(XAttrSetFlag.CREATE));
} catch (IOException e) {
  if (e.getMessage() != null && e.getMessage().contains("already exists")) {
    fs.setXAttr(path, name, value, EnumSet.of(XAttrSetFlag.REPLACE));
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: setXAttr(path, name, value, EnumSet.of(CREATE)) when 'name' is already stored on the path; re-running an initializer that uses CREATE-only after a previous successful run.

Common situations: Idempotent metadata writers re-running after partial job failure; two clients racing to initialize the same attribute (one wins with CREATE, the other loses); migration jobs that re-tag existing files.

Related errors


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