apache/hadoop · error · IOException
srcIIP.getPath() + " can't be moved into an encryption zone.
Error message
srcIIP.getPath() + " can't be moved into an encryption zone."
What it means
IOException from EncryptionZoneManager.checkMoveValidity: the rename destination's parent lies inside an encryption zone while the source does not. A plaintext file renamed into an EZ would keep its unencrypted blocks while appearing to live in an encrypted zone, violating the zone's guarantee, so the move is rejected.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/EncryptionZoneManager.java:496
* @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) {
checkMoveValidityForReencryption(dstIIP.getPath(),
dstParentEZI.getINodeId());
}View on GitHub (pinned to 2add963021)
Solutions
- Copy instead of rename: hdfs dfs -cp <src> <dst> && hdfs dfs -rm <src> -- new writes inside the EZ are transparently encrypted with the zone's key, then delete the plaintext original.
- For bulk data use hadoop distcp (copy semantics; destination files get encrypted).
- Fix the pipeline: write directly into the EZ in the first place so no move is needed.
Example fix
# before: fails hdfs dfs -mv /ingest/upload.csv /secure/upload.csv # after: cp writes through the EZ (encrypted), then remove plaintext source hdfs dfs -cp /ingest/upload.csv /secure/upload.csv hdfs dfs -rm /ingest/upload.csv
Defensive patterns
Strategy: validation
Validate before calling
EncryptionZone s = dfs.getEncryptionZoneForPath(src);
EncryptionZone d = dfs.getEncryptionZoneForPath(dst);
if (d != null && s == null) {
// rename INTO a zone is rejected: write/copy into the zone instead (new writes get encrypted)
} 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("moved into an encryption zone")) {
copyThenDelete(src, dst); // cp re-encrypts under the zone key, then rm the plaintext source
} else { throw e; }
} Prevention
- Ingest directly into the encryption zone; do not stage outside and try to mv in.
- Check getEncryptionZoneForPath(dst) before move operations in pipeline code.
- Use distcp for bulk cross-boundary migrations (copy semantics, encryption-aware).
When it happens
Trigger: hdfs dfs -mv (or FileSystem.rename) of a file/dir from a non-EZ path into a directory whose nearest EZ ancestor exists, e.g., moving raw uploads from /ingest into /secure for 'protection'.
Common situations: Ingest designs that stage plaintext then try to 'move into' an encryption zone; consolidation scripts; users assuming mv into a zone encrypts in place.
Related errors
- srcIIP.getPath() + " can't be moved from 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/09355cb56b29c8ca.
Report an issue: GitHub.