{"record":{"id":"791b968eeabdfaf1","repo":"apache/hadoop","slug":"no-matching-attributes-found-for-remove-operation","errorCode":null,"errorMessage":"No matching attributes found for remove operation","messagePattern":"No matching attributes found for remove operation","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirXAttrOp.java","lineNumber":186,"sourceCode":"      boolean logRetryCache) throws IOException {\n    FSDirXAttrOp.checkXAttrsConfigFlag(fsd);\n    XAttrPermissionFilter.checkPermissionForApi(\n        pc, xAttr, FSDirectory.isReservedRawName(src));\n\n    List<XAttr> xAttrs = Lists.newArrayListWithCapacity(1);\n    xAttrs.add(xAttr);\n    INodesInPath iip;\n    fsd.writeLock();\n    try {\n      iip = fsd.resolvePath(pc, src, DirOp.WRITE);\n      src = iip.getPath();\n      checkXAttrChangeAccess(fsd, iip, xAttr, pc);\n\n      List<XAttr> removedXAttrs = unprotectedRemoveXAttrs(fsd, iip, xAttrs);\n      if (removedXAttrs != null && !removedXAttrs.isEmpty()) {\n        fsd.getEditLog().logRemoveXAttrs(src, removedXAttrs, logRetryCache);\n      } else {\n        throw new IOException(\n            \"No matching attributes found for remove operation\");\n      }\n    } finally {\n      fsd.writeUnlock();\n    }\n    return fsd.getAuditFileInfo(iip);\n  }\n\n  /**\n   * Remove xattrs from the inode, and return the <em>removed</em> xattrs.\n   * @return the <em>removed</em> xattrs.\n   */\n  static List<XAttr> unprotectedRemoveXAttrs(\n      FSDirectory fsd, final INodesInPath iip, final List<XAttr> toRemove)\n      throws IOException {\n    assert fsd.hasWriteLock();\n    INode inode = FSDirectory.resolveLastINode(iip);\n    int snapshotId = iip.getLatestSnapshotId();","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirXAttrOp.java#L168-L204","documentation":"removeXAttr works from the inode's stored xattrs: unprotectedRemoveXAttrs returns the attributes that were actually removed so they can be journaled. If nothing matched, there is nothing to log and the operation throws IOException('No matching attributes found for remove operation'); the attribute simply is not set on that path.","triggerScenarios":"fs.removeXAttr(path, name) for an xattr that is not present: never set, already removed by a previous run, or wrong namespace/name spelling.","commonSituations":"Idempotent cleanup code removing markers unconditionally; double-executed jobs; schema drift between the setter and the remover.","solutions":["Check presence first with fs.listXAttrs(path) and remove only names present","Make removal tolerant: catch IOException and ignore the no-matching-attributes outcome after verifying the message","Prefer the exists-check plus remove pattern so the ignore branch is explicit"],"exampleFix":"// before\nfs.removeXAttr(path, \"user.mytag\"); // throws when absent\n\n// after\nif (fs.listXAttrs(path).contains(\"user.mytag\")) {\n  fs.removeXAttr(path, \"user.mytag\");\n}","handlingStrategy":"try-catch","validationCode":"if (fs.listXAttrs(path).contains(name)) {\n  fs.removeXAttr(path, name);\n}","typeGuard":null,"tryCatchPattern":"try {\n  fs.removeXAttr(path, name);\n} catch (IOException e) {\n  if (e.getMessage() == null || !e.getMessage().contains(\"No matching attributes\")) {\n    throw e; // only swallow the absent-attribute case\n  }\n}","preventionTips":["Make xattr cleanup idempotent: check presence before removing","Tolerate double-executed cleanup jobs by catching the no-match case","Keep setter and remover xattr schemas in sync"],"tags":["hdfs","xattr","remove","not-found","idempotency"],"backgroundTag":"xattr-not-found","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}