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

  1. 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.
  2. For bulk data use hadoop distcp (copy semantics; destination files get encrypted).
  3. 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

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


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/09355cb56b29c8ca. Report an issue: GitHub.