Docs → Fresh root-on-ZFS install

Fresh install: encrypted root-on-ZFS Omarchy

For a machine whose disk you are willing to erase. You get Omarchy Quattro on a natively-encrypted ZFS pool, booted by ZFSBootMenu, with one passphrase prompt and boot environments you can roll back to.

Status: beta

The 2026.08.20.1 image was taken through this exact sequence before publishing. Fresh disk, fresh UEFI variables, no manual repair. Ending at a logged-in desktop. That is the bar for a release, rather than "it worked once on the author's machine". It is still young software that repartitions disks. Do not point it at a machine holding the only copy of anything.

1. Download and verify the ISO

curl -LO https://dl.omarchy-zfs.com/omarchy-zfs-2026.08.20.1-x86_64-quattro.iso
curl -LO https://dl.omarchy-zfs.com/omarchy-zfs-2026.08.20.1-x86_64-quattro.iso.sha256
sha256sum -c omarchy-zfs-2026.08.20.1-x86_64-quattro.iso.sha256

You want OK. About 6.2 GB. It carries a full offline package mirror so the install never touches the network.

Prefer to build it yourself? iso/build.sh in the repo clones the official Omarchy ISO at a pinned commit and applies a small overlay. No fork. It needs Docker and about 15 GB.

2. Write it to a USB stick

# Find the stick. Get this wrong and you erase the wrong disk.
lsblk -o NAME,SIZE,MODEL,TRAN

sudo dd if=omarchy-zfs-2026.08.20.1-x86_64-quattro.iso of=/dev/sdX bs=4M \
     status=progress oflag=sync
Check the device name twice

dd will happily overwrite your system disk. /dev/sdX is the whole stick, not a partition (/dev/sdb, not /dev/sdb1).

3. Boot it, and catch the 15-second question

Boot the stick in UEFI mode with Secure Boot off. The live environment comes up and asks:

Install with root-on-ZFS + ZFSBootMenu (experimental)?
    Yes      [No]
←→ toggle · enter submit · y Yes · n No
The default is No, and it times out in 15 seconds

Press y. If you miss it, the stock Omarchy installer takes over and you get a normal btrfs install. Which is a perfectly good outcome, just not this one. Reboot the stick to try again.

4. Answer the installer

Questions come in this order. Defaults are in brackets.

QuestionWhat to pick
Pool modeCreate a new pool. (The other option adopts a pool you already made. Useful for recovery, see route 2.)
Pool topologysingle, mirror, raidz1, raidz2, raidz3. One disk means single. A mirror needs two disks of similar size and survives one failing.
DiskThe disk that gets both the EFI partition and the pool. Everything on it is destroyed.
Wipe confirmationIt lists the exact devices. Read the list.
Pool passphrase (twice, ≥8 chars) This is the encryption passphrase and your login password, so there is one secret to remember on day one. You can split them later. See below.
Hostname [omarchy]Anything.
Timezone [UTC]e.g. America/New_York.
Locale [en_US.UTF-8]Anything valid.
Username [user]Your daily login, not root.

Then it runs unattended for roughly 10–15 minutes and finishes with Bootstrap complete. Along the way it prints two verifications worth noticing:

omarchy-zfs-embed-pool-key: verified etc/zfs/zroot.key present in /boot/initramfs-linux.img
✓ Verified: pool key embedded in the in-pool initramfs (single passphrase prompt)
✓ Boot-readiness verified: kernel+initramfs pairs, ZBM image, hostid

If instead you see “pool key is NOT embedded”, the install is still fine. You will simply be asked for the passphrase twice at boot. If a boot-readiness check fails, the installer refuses to finish and leaves everything mounted so you can look around. It stops rather than hand you a system that cannot boot.

What it builds

A GPT disk with a 1 GB EFI partition and the rest given to a pool named zroot:

zpool create -o ashift=12 -o autotrim=on \
  -o compatibility=openzfs-2.4-linux \
  -O acltype=posixacl -O xattr=sa -O dnodesize=auto \
  -O compression=zstd -O normalization=formD \
  -O relatime=on -O atime=off \
  -O encryption=aes-256-gcm -O keyformat=passphrase  zroot ...

compatibility=openzfs-2.4-linux caps the feature flags to what ZFSBootMenu release builds can read. A pool with newer features enabled is a pool ZBM cannot open.

DatasetMounted atWhy separate
zroot/ROOT/default/The boot environment. canmount=noauto. ZFSBootMenu chooses it.
zroot/data/home/homeSurvives reinstalling or rolling back the OS.
zroot/data/root/rootSame, for root's home.
zroot/var/log, zroot/var/log/journal/var/logLogs should not vanish when you roll back the OS. journal gets acltype=posixacl because journald needs it.
zroot/var/cache, zroot/var/tmp/var/cache, /var/tmpChurn you never want in a snapshot of the OS.
zroot/var/lib/docker, libvirt, machinesunder /var/libContainer and VM images, kept out of OS snapshots.
zroot/keystore/etc/zfs/keysKey material for any secondary pools.

5. First boot

Remove the USB stick and reboot. You should see, in order:

  1. ZFSBootMenu asking Enter passphrase for 'zroot':. Type the passphrase you chose.
  2. A brief boot, then the Omarchy greeter.
  3. Log in with the same passphrase.

One prompt, not two. That works because the pool keyfile lives inside the initramfs that is itself stored in the encrypted pool: ZFSBootMenu unlocks the pool to read /boot, then the kernel it boots finds the key already there. The key never touches the unencrypted EFI partition, and omarchy-refresh-zbm fails loudly if it ever finds it there.

ZFSBootMenu is worth learning

At the ZBM menu you can pick an older boot environment, roll a snapshot back before booting it, edit the kernel command line, or drop to a recovery shell with your pool imported. All before the OS starts. This is the thing a btrfs+snapper setup gives you too, and the reason a ZFS root beats ZFS-on-/home if you want it.

6. Verify what you got

omarchy-fs-type                 # -> zfs
zpool status                     # ONLINE, no errors
zfs list -o name,used,mountpoint
zpool get compatibility zroot    # openzfs-2.4-linux
systemctl is-enabled zfs-import-cache zfs-mount zfs.target
systemctl list-timers omarchy-zfs-scrub.timer

All the ZFS services must be enabled. If any says disabled, enable it. A pool that imports but never mounts its datasets produces a system with no /home, and the symptom is a greeter that accepts your password and then bounces you straight back. It looks exactly like a wrong password.

sudo systemctl enable zfs-import-cache.service zfs-mount.service \
  zfs-zed.service zfs-import.target zfs.target

Changing the passphrase later

The pool's wrapping key is the contents of /etc/zfs/zroot.key, which is what gets embedded in the initramfs. Your login password is a separate thing that merely started out identical. To change either:

Login password only

passwd            # does not touch the pool

Pool passphrase

# 1. Put the new passphrase in the keyfile, with NO trailing newline
printf '%s' 'new-passphrase-here' | sudo tee /etc/zfs/zroot.key >/dev/null
sudo chmod 600 /etc/zfs/zroot.key

# 2. Re-wrap the pool key from that file
sudo zfs change-key -o keylocation=file:///etc/zfs/zroot.key zroot

# 3. Rebuild the initramfs + ZFSBootMenu so the embedded key matches
sudo omarchy-refresh-zbm
Test before you rely on it. And note what is not tested here

The install-and-boot path above is verified on every image we publish. This rotation procedure is not in that automated matrix: it follows OpenZFS's documented behaviour for change-key (the new wrapping key is read from the location you name), but you should prove it on your own machine rather than take it on faith.

So: reboot once and confirm the new passphrase unlocks at ZFSBootMenu before you discard the old one. If you skip step 3, ZBM will want the new passphrase while the initramfs still carries the old key. That is a second prompt, not a lockout, and sudo omarchy-refresh-zbm fixes it.

When it goes wrong

“Datasets above are not mounted; refusing to continue”

The installer's own gate. It means a dataset's mountpoint would have been shadowed, so writes would land in the wrong dataset and disappear at boot. Nothing has been unmounted. You can inspect. Upgrade to the current ISO; this was a real bug in the 2026.08.20 image, fixed in 2026.08.20.1.

Asked for the passphrase twice

The pool key is not in the initramfs. Harmless but annoying:

sudo omarchy-zfs-embed-pool-key   # rebuild the in-pool initramfs with the key
sudo omarchy-refresh-zbm          # or do both plus ZBM in one step

“pool was previously in use from another system”

Usually not a problem: ZFSBootMenu leaves the pool imported when it hands off to the kernel, and the import retries and succeeds. If a boot really does stop here, the hostid in the initramfs disagrees with the pool label. Compare hostid with what the message reports, and check /etc/hostid exists. omarchy-zfs keeps /etc/hostid in every initramfs with a static mkinitcpio drop-in so this stays boring.

Emergency shell, no pool

Boot the ISO again, then:

zpool import -f -R /mnt zroot
zfs load-key zroot            # or: zfs load-key -L prompt zroot
zfs mount zroot/ROOT/default
zfs mount -a
arch-chroot /mnt

From there you can rebuild the initramfs (omarchy-refresh-zbm), fix a password (passwd <user>), or read /var/log/journal.

Next