{"record":{"id":"8f6371662cc059f4","repo":"apache/hadoop","slug":"is-not-an-encryption-zone","errorCode":null,"errorMessage":"{} is not an encryption zone.","messagePattern":"(.+?) is not an encryption zone\\.","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":707,"sourceCode":"   * the provider's local cache, then generate a new edek.\n   * <p>\n   * The encryption key version of the newly generated edek will be used as\n   * the target key version of this re-encryption - meaning all edeks'\n   * keyVersion are compared with it, and only sent to the KMS for re-encryption\n   * when the version is different.\n   * <p>\n   * Note: KeyProvider has a getCurrentKey interface, but that is under\n   * a different ACL. HDFS should not try to operate on additional ACLs, but\n   * rather use the generate ACL it already has.\n   */\n  static String getCurrentKeyVersion(final FSDirectory dir,\n      final FSPermissionChecker pc, final String zone) throws IOException {\n    assert dir.getProvider() != null;\n    assert !dir.hasReadLock();\n    final String keyName = FSDirEncryptionZoneOp.getKeyNameForZone(dir,\n        pc, zone);\n    if (keyName == null) {\n      throw new IOException(zone + \" is not an encryption zone.\");\n    }\n    // drain the local cache of the key provider.\n    // Do not invalidateCache on the server, since that's the responsibility\n    // when rolling the key version.\n    dir.getProvider().drain(keyName);\n    final EncryptedKeyVersion edek;\n    try {\n      edek = dir.getProvider().generateEncryptedKey(keyName);\n    } catch (GeneralSecurityException gse) {\n      throw new IOException(gse);\n    }\n    Preconditions.checkNotNull(edek);\n    return edek.getEncryptionKeyVersionName();\n  }\n\n  /**\n   * Resolve the zone to an inode, find the encryption zone info associated with\n   * that inode, and return the key name. Does not contact the KMS.","sourceCodeStart":689,"sourceCodeEnd":725,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirEncryptionZoneOp.java#L689-L725","documentation":"Thrown by the NameNode when a re-encryption start targets a path that is not inside any encryption zone. FSNamesystem.reencryptEncryptionZoneInt calls FSDirEncryptionZoneOp.getCurrentKeyVersion (FSNamesystem.java:8387) to fetch the zone's latest key version before starting; getKeyNameForZone returns null when no encryption zone covers the path, which is converted to this IOException. No state has changed when it fires; the reencrypt request is simply rejected.","triggerScenarios":"Running `hdfs crypto -reencrypt -start -path /data` where neither /data nor any ancestor is an encryption zone; invoking the reencrypt RPC with ReencryptAction.START on a plain directory; passing a zone path that was deleted and recreated without re-creating the zone (e.g., a copy restored under .Trash); a case or URL-encoding mismatch that makes the EZ xattr lookup miss.","commonSituations":"KMS-enabled clusters where the zone was created on a different path than the script assumes; the EZ directory was rmr'd and restored from trash so the zone xattr is gone; ops tooling that assumes all of /user/<name> is encrypted but only a subdirectory was zoned; data moved between clusters without recreating zones.","solutions":["Run `hdfs crypto -listZones` and re-issue the reencrypt start with the exact zone root path (or a path directly under it).","If no zone exists yet: `hdfs key -create <keyName>` in the KMS, then `hdfs crypto -createZone -keyName <keyName> -path <path>`, then start re-encryption.","Confirm the path is actually encrypted with `hdfs crypto -getFileEncryptionInfo -path <path>`; an empty result means it is not in a zone.","If the zone was deleted and the data restored without xattrs, recreate the zone on the restored directory before re-encrypting."],"exampleFix":"# before\nhdfs crypto -reencrypt -start -path /data   # fails: /data is not an encryption zone\n\n# after\nhdfs crypto -listZones                      # find the real zone root, e.g. /secure/data\nhdfs crypto -reencrypt -start -path /secure/data","handlingStrategy":"try-catch","validationCode":"import org.apache.hadoop.fs.EncryptionZone;\nimport org.apache.hadoop.hdfs.DistributedFileSystem;\n\nstatic boolean inEncryptionZone(DistributedFileSystem dfs, Path p) throws IOException {\n  String target = p.toUri().getPath();\n  for (EncryptionZone z : dfs.listEncryptionZones()) {\n    String zone = z.getPath().toUri().getPath();\n    if (target.equals(zone) || target.startsWith(zone + \"/\")) return true;\n  }\n  return false;\n}\n// before reencrypt start:\nif (!inEncryptionZone(dfs, zonePath)) {\n  throw new IllegalArgumentException(zonePath + \" is not in any encryption zone; see hdfs crypto -listZones\");\n}","typeGuard":null,"tryCatchPattern":"import org.apache.hadoop.fs.HdfsAdmin;\nimport org.apache.hadoop.fs.ReencryptAction;\n\ntry {\n  new HdfsAdmin(zonePath.toUri(), conf).reencryptEncryptionZone(zonePath, ReencryptAction.START);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().endsWith(\"is not an encryption zone.\")) {\n    // actionable retry: list zones and re-run against the true zone root\n    LOG.warn(\"{} is not an encryption zone; run hdfs crypto -listZones\", zonePath);\n  }\n  throw e;\n}","preventionTips":["Store encryption zone roots in configuration and validate them against `hdfs crypto -listZones` at deploy time.","Never point re-encryption at data restored from trash; recreate the zone first.","Smoke-test with `hdfs crypto -getFileEncryptionInfo -path <p>` before batch re-encryption runs."],"tags":["hdfs","encryption-zone","kms","hdfs-crypto","re-encryption"],"backgroundTag":"encryption-zone-not-found","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}