apache/hadoop · error · IOException
srcIIP.getPath() + " can't be moved from an encryption zone.
Error message
srcIIP.getPath() + " can't be moved from an encryption zone."
What it means
IOException from EncryptionZoneManager.checkMoveValidity (reached via FSDirRenameOp): a rename was requested where the source's parent is inside an encryption zone but the destination is not. HDFS rejects renames out of an encryption zone because the file's EDEK belongs to the zone's key -- a rename would carry ciphertext outside the zone's key context and silently break the zone's guarantees, so no cross-boundary rename is allowed.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/EncryptionZoneManager.java:493
*
* @param srcIIP source IIP
* @param dstIIP destination IIP
* @throws IOException if the src cannot be renamed to the dst
*/
void checkMoveValidity(INodesInPath srcIIP, INodesInPath dstIIP)
throws IOException {
assert dir.hasReadLock();
if (!hasCreatedEncryptionZone()) {
return;
}
final EncryptionZoneInt srcParentEZI =
getParentEncryptionZoneForPath(srcIIP);
final EncryptionZoneInt dstParentEZI =
getParentEncryptionZoneForPath(dstIIP);
final boolean srcInEZ = (srcParentEZI != null);
final boolean dstInEZ = (dstParentEZI != null);
if (srcInEZ && !dstInEZ) {
throw new IOException(
srcIIP.getPath() + " can't be moved from an encryption zone.");
} else if (dstInEZ && !srcInEZ) {
throw new IOException(
srcIIP.getPath() + " can't be moved into an encryption zone.");
}
if (srcInEZ) {
if (!srcParentEZI.equals(dstParentEZI)) {
final String srcEZPath = getFullPathName(srcParentEZI.getINodeId());
final String dstEZPath = getFullPathName(dstParentEZI.getINodeId());
final StringBuilder sb = new StringBuilder(srcIIP.getPath());
sb.append(" can't be moved from encryption zone ").append(srcEZPath)
.append(" to encryption zone ").append(dstEZPath).append(".");
throw new IOException(sb.toString());
}
checkMoveValidityForReencryption(srcIIP.getPath(),
srcParentEZI.getINodeId());
} else if (dstInEZ) {View on GitHub (pinned to 2add963021)
Solutions
- Replace the rename with copy-then-delete: hdfs dfs -cp <src> <dst> && hdfs dfs -rm <src> -- the client decrypts on read and writes plaintext at the destination.
- For large moves use hadoop distcp (it also performs copy+delete and handles KMS auth).
- Restructure layout so the whole workflow lives inside one encryption zone (zones must be created on empty directories, so plan this up front).
Example fix
# before: fails hdfs dfs -mv /secure/data.csv /scratch/data.csv # after: copy (client decrypts), then remove the source hdfs dfs -cp /secure/data.csv /scratch/data.csv hdfs dfs -rm /secure/data.csv
Defensive patterns
Strategy: validation
Validate before calling
EncryptionZone s = dfs.getEncryptionZoneForPath(src);
EncryptionZone d = dfs.getEncryptionZoneForPath(dst);
boolean srcIn = s != null, dstIn = d != null;
if (srcIn && !dstIn) {
// rename OUT of a zone is rejected: plan copy-then-delete instead
} Type guard
static boolean isEncryptionZoneMoveViolation(IOException e) {
return e.getMessage() != null && e.getMessage().contains("encryption zone");
} Try / catch
try {
fs.rename(src, dst);
} catch (RemoteException re) {
IOException e = re.unwrapRemoteException(IOException.class);
if (e.getMessage() != null && e.getMessage().contains("can't be moved")) {
copyThenDelete(src, dst); // cp decrypts to plaintext outside the zone, then rm
} else { throw e; }
} Prevention
- Before any mv across directories, compare hdfs crypto zone membership of src and dst (getEncryptionZoneForPath).
- Design pipelines to stay inside a single zone; treat cross-zone moves as copies.
- Wrap move logic in a helper that falls back to copy+delete when zones differ.
When it happens
Trigger: hdfs dfs -mv (or FileSystem.rename) from /zone/src/file to a path whose nearest EZ ancestor is null: e.g., moving encrypted working data to a shared scratch area, temp dirs, or a landing zone outside the EZ.
Common situations: ETL pipelines that stage inside an encryption zone and 'move' results to a general-purpose directory; users trying to relocate data to quota-free or differently-governed paths; scripts written before the EZ existed.
Related errors
- srcIIP.getPath() + " can't be moved into an encryption zone.
- srcIIP.getPath() + " can't be moved from encryption zone " +
- pathName + " can't be moved because encryption zone " + getF
- {} doesn't support renameSnapshot
- '{}' copy from '/.reserved/raw' to non '/.reserved/raw'. Eit
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/3eecec299589064e.
Report an issue: GitHub.