{"record":{"id":"9fd1760124d8e282","repo":"apache/hadoop","slug":"could-not-find-reencryption-xattr-for-file-ii","errorCode":null,"errorMessage":"\"Could not find reencryption XAttr for file \" + iip.getPath()","messagePattern":"\"Could not find reencryption XAttr for file \" \\+ iip\\.getPath\\(\\)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirEncryptionZoneOp.java","lineNumber":369,"sourceCode":"            status.getNumReencryptionFailures(), Time.now(), null);\n\n    final ZoneEncryptionInfoProto newZoneProto = PBHelperClient\n        .convert(PBHelperClient.convert(zoneProto.getSuite()),\n            PBHelperClient.convert(zoneProto.getCryptoProtocolVersion()),\n            zoneProto.getKeyName(), newRiProto);\n\n    final XAttr xattr = XAttrHelper\n        .buildXAttr(CRYPTO_XATTR_ENCRYPTION_ZONE, newZoneProto.toByteArray());\n    return xattr;\n  }\n\n  private static ZoneEncryptionInfoProto getZoneEncryptionInfoProto(\n      final INodesInPath iip) throws IOException {\n    final XAttr fileXAttr = FSDirXAttrOp.unprotectedGetXAttrByPrefixedName(\n        iip.getLastINode(), iip.getPathSnapshotId(),\n        CRYPTO_XATTR_ENCRYPTION_ZONE);\n    if (fileXAttr == null) {\n      throw new IOException(\n          \"Could not find reencryption XAttr for file \" + iip.getPath());\n    }\n    try {\n      return ZoneEncryptionInfoProto.parseFrom(fileXAttr.getValue());\n    } catch (InvalidProtocolBufferException e) {\n      throw new IOException(\n          \"Could not parse file encryption info for \" + \"inode \" + iip\n              .getPath(), e);\n    }\n  }\n\n  /**\n   * Save the batch's edeks to file xattrs.\n   */\n  static void saveFileXAttrsForBatch(FSDirectory fsd,\n      List<FileEdekInfo> batch) {\n    assert fsd.getFSNamesystem().hasWriteLock(RwLockMode.FS);\n    if (batch != null && !batch.isEmpty()) {","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirEncryptionZoneOp.java#L351-L387","documentation":"Reencryption operations load the zone's raw CRYPTO_XATTR_ENCRYPTION_ZONE xattr via getZoneEncryptionInfoProto; when that xattr is absent the method throws IOException 'Could not find reencryption XAttr for file <path>'. Callers are the reencryption paths (updateReencryptionSubmitted from 'hdfs crypto -reencrypt -start/-cancel', progress updates from the reencryption thread, and completion handling), so in practice you see this when issuing a reencrypt command on a directory that is not an encryption zone root, or whose zone xattr was lost/corrupted.","triggerScenarios":"'hdfs crypto -reencrypt -start <dir>' where <dir> is not an EZ root (a plain directory, or a subdirectory inside a zone rather than the zone root itself); reencrypting a path whose zone xattr was removed; races where the zone is deleted while a reencrypt command is in flight.","commonSituations":"Operators pointing the reencrypt command at a subdirectory of the zone instead of the zone root; automation that assumes any path under an EZ accepts -reencrypt; a zone root that was deleted and recreated so the old path no longer carries the xattr.","solutions":["Run the reencrypt command against the encryption zone ROOT (the exact path shown by 'hdfs crypto -listZones'), not a subdirectory.","Verify the path is a zone root first: hdfs crypto -listZones, or HdfsAdmin.getEncryptionZoneForPath(path) and check ez.getPath().equals(path).","If the root really lost its zone xattr (deleted/recreated), recreate the zone (createEncryptionZone) before reencrypting."],"exampleFix":"# before\nhdfs crypto -reencrypt -start /secure/subdir  # subdir is not the zone root\n\n# after\nhdfs crypto -listZones   # shows zone root /secure\nhdfs crypto -reencrypt -start /secure","handlingStrategy":"validation","validationCode":"HdfsAdmin admin = new HdfsAdmin(fs.getUri(), conf);\nEncryptionZone ez = admin.getEncryptionZoneForPath(path);\nif (ez == null || !ez.getPath().equals(path)) {\n  throw new IllegalArgumentException(\n      path + \" is not an encryption zone root; reencrypt the zone root \"\n      + (ez == null ? \"(create the zone first)\" : ez.getPath()));\n}","typeGuard":null,"tryCatchPattern":"catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Could not find reencryption XAttr\")) {\n    // resolve the actual zone root and retry against it\n    EncryptionZone ez = admin.getEncryptionZoneForPath(path);\n    if (ez != null) { reencryptStart(ez.getPath(), keyVersion); }\n  } else { throw e; }\n}","preventionTips":["Always resolve the zone root with getEncryptionZoneForPath and reencrypt exactly that path.","Automation should treat 'zone root changed' (delete + recreate) as a first-class failure mode and re-resolve.","Keep 'hdfs crypto -listZones' output in change-management tickets when scheduling reencryption."],"tags":["hdfs","encryption-zone","reencryption","xattr","key-rotation"],"backgroundTag":"reencryption-xattr-missing","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}