apache/hadoop · error · IOException
{} is not an encryption zone.
Error message
{} is not an encryption zone. What it means
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.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirEncryptionZoneOp.java:707
* the provider's local cache, then generate a new edek.
* <p>
* The encryption key version of the newly generated edek will be used as
* the target key version of this re-encryption - meaning all edeks'
* keyVersion are compared with it, and only sent to the KMS for re-encryption
* when the version is different.
* <p>
* Note: KeyProvider has a getCurrentKey interface, but that is under
* a different ACL. HDFS should not try to operate on additional ACLs, but
* rather use the generate ACL it already has.
*/
static String getCurrentKeyVersion(final FSDirectory dir,
final FSPermissionChecker pc, final String zone) throws IOException {
assert dir.getProvider() != null;
assert !dir.hasReadLock();
final String keyName = FSDirEncryptionZoneOp.getKeyNameForZone(dir,
pc, zone);
if (keyName == null) {
throw new IOException(zone + " is not an encryption zone.");
}
// drain the local cache of the key provider.
// Do not invalidateCache on the server, since that's the responsibility
// when rolling the key version.
dir.getProvider().drain(keyName);
final EncryptedKeyVersion edek;
try {
edek = dir.getProvider().generateEncryptedKey(keyName);
} catch (GeneralSecurityException gse) {
throw new IOException(gse);
}
Preconditions.checkNotNull(edek);
return edek.getEncryptionKeyVersionName();
}
/**
* Resolve the zone to an inode, find the encryption zone info associated with
* that inode, and return the key name. Does not contact the KMS.View on GitHub (pinned to 2add963021)
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.
Example fix
# before hdfs crypto -reencrypt -start -path /data # fails: /data is not an encryption zone # after hdfs crypto -listZones # find the real zone root, e.g. /secure/data hdfs crypto -reencrypt -start -path /secure/data
Defensive patterns
Strategy: try-catch
Validate before calling
import org.apache.hadoop.fs.EncryptionZone;
import org.apache.hadoop.hdfs.DistributedFileSystem;
static boolean inEncryptionZone(DistributedFileSystem dfs, Path p) throws IOException {
String target = p.toUri().getPath();
for (EncryptionZone z : dfs.listEncryptionZones()) {
String zone = z.getPath().toUri().getPath();
if (target.equals(zone) || target.startsWith(zone + "/")) return true;
}
return false;
}
// before reencrypt start:
if (!inEncryptionZone(dfs, zonePath)) {
throw new IllegalArgumentException(zonePath + " is not in any encryption zone; see hdfs crypto -listZones");
} Try / catch
import org.apache.hadoop.fs.HdfsAdmin;
import org.apache.hadoop.fs.ReencryptAction;
try {
new HdfsAdmin(zonePath.toUri(), conf).reencryptEncryptionZone(zonePath, ReencryptAction.START);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().endsWith("is not an encryption zone.")) {
// actionable retry: list zones and re-run against the true zone root
LOG.warn("{} is not an encryption zone; run hdfs crypto -listZones", zonePath);
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- "Can't create an encryption zone for " + src + " since no ke
- "Key " + keyName + " doesn't exist."
- Too many retries because of encryption zone operations
- '{}' copy from '/.reserved/raw' to non '/.reserved/raw'. Eit
- '{}' copy from non '/.reserved/raw' to '/.reserved/raw'. Eit
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/8f6371662cc059f4.
Report an issue: GitHub.