Encrypting previously unencrypted data, such as a legacy ZFS pool, requires a reliable migration strategy. The most robust way to achieve this is by using the powerful ZFS data stream mechanism: zfs send and zfs recv.
The core procedure is simple: create a snapshot, transfer this snapshot, and receive it at a new, encrypted destination.
The Encryption Inheritance Pitfall
The critical complexity arises when dealing with encryption inheritance. For the target volume to inherit the key and encryption properties from its parent, you must be careful with the zfs recv command flags.
- Scenario: If the parent dataset (
tank/kvm/100) is already encrypted, and the target (tank/kvm/100/rootfs) is a child dataset, the child will not automatically be encrypted by default when receiving a stream.
The Flag Logic: -o vs. -x
You must use the -x flag (eXclude) to enforce inheritance, rather than the -o flag (override):
- Using
-o(Override): Explicitly setting encryption properties with-o encryption=...will lead to the new dataset having its own key, even if the parent is encrypted.- Consequence: This results in two separate keys in the system, complicating key management (
zfs load-key -aloads 2 keys).
- Consequence: This results in two separate keys in the system, complicating key management (
- Using
-x(Exclude/Inherit): Using-xexcludes the encryption properties from the received stream. If the destination parent is already an encryption root, the child dataset will automatically inherit the parent’s key and encryption properties.
The correct command to enforce inheritance and use the parent’s key is:
zfs recv -o mountpoint=none -x encryption -x keylocation -x keyformat tank/new_encrypted_pool/dataset
This forces the target to inherit the properties set at its parent’s level.
A Full Migration Example
This example demonstrates a complete, encrypted dataset transfer between two systems over a network using the mbuffer utility for flow control and verification tools.
Receiver System
The receiver initiates the pipeline, waiting for the stream and directing the data into the new, encrypted dataset.
# Receiver: mbuffer reads the network stream and pipes it to zfs recv.
# -x flags ensure properties are inherited from the parent pool (tank/srv/mio).
~# mbuffer -q -s 128k -m 1G -I 10.0.0.3:13371 | pv -bp | zfs recv -o mountpoint=none -x encryption -x keylocation -x keyformat tank/srv/mio/disk2-orig
24.4GiB [ <=> ]
Sender System
The sender creates a recursive snapshot, which is then sent across the network.
~# zfs snapshot tank/srv/mio2/disk2@transfer
~# zfs send -c -L -R tank/srv/mio2/disk2@transfer | mbuffer -s 128k -m 1G -O 10.0.0.4:13371
summary: 24.4 GiByte in 3min 42.7sec - average of 112 MiB/s
Note: The use of mbuffer and pv provides essential Observability into the transfer rate and progress, which is extremly helpful for long-running network operations.
Verification of Encryption Root
After the transfer is complete, verification confirms that the new dataset uses the parent pool’s key.
~# zfs get all tank/srv/mio/disk2-orig
[..]
tank/srv/mio/disk2-orig encryption aes-256-gcm -
tank/srv/mio/disk2-orig keylocation none default
tank/srv/mio/disk2-orig keyformat raw -
tank/srv/mio/disk2-orig encryptionroot tank/srv/mio -
tank/srv/mio/disk2-orig keystatus available -
The output encryptionroot tank/srv/mio - confirms that the encryption properties are inherited from the parent pool (tank/srv/mio), meaning only one key is loaded for the entire hierarchy.
Alternative: zfs send and zfs recv can be used on the same system without network transfer simply by piping the output to the receiver command.
Sources / See Also
- ZFS Manpage:
zfs-recvDetails on the behavior of -o (override) and -x (exclude) flags, and property inheritance during stream reception.https://openzfs.github.io/openzfs-docs/man/master/8/zfs-recv.8.html - OpenZFS Documentation: Sending and Receiving Encrypted Data Official guide explaining the default decryption/re-encryption behavior and the use of the -w crypto (raw) flag for encrypted streams.
https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/manage-zfs/sending-receiving-encrypted-zfs-data.html - Zrepl Documentation: Send & Recv Options In-depth technical explanation of property replication and inheritance logic, specifically clarifying the difference between overriding and excluding properties upon reception.
https://zrepl.github.io/configuration/sendrecvoptions.html