Every failure mode this tooling can produce, and how to get out of it.
Interactive-shell warning. These commands are typed by hand, often at 3am. Many shells alias
cp='cp -i',rm='rm -i',cat=bat,find=fd. An interactive prompt you do not notice can silently skip a critical copy. Use absolute paths (/usr/bin/cp -f) or prefix withcommand.
First: what state are you in?
Boot the Fedora Asahi live USB (UBOOT-BOOTFLOW.md) and look:
lsblk -f
sudo cryptsetup luksDump /dev/nvme0n1p6 | head -20| What you see | State | Go to |
|---|---|---|
Root partition still btrfs, no LUKS header |
Encryption never started | Undo the shrink |
luksDump shows a LUKS2 header and "online reencryption in progress" |
Interrupted mid-encryption | Resume |
| Valid LUKS2 header, container opens fine, but the box will not boot | Encryption fine, boot config wrong | Repair boot config |
| Passphrase accepted, root mounts, then services fail en masse | SELinux mislabels | Relabel |
luksDump fails / "device is not a valid LUKS device" |
Header damaged | Restore the header |
Boots to a GRUB rescue> prompt |
ESP stub was overwritten | Restore the ESP stub |
Encryption never started — undo the btrfs shrink
Step 1 shrinks btrfs by 32 MB to make room for the LUKS header. If the script died between that and the encryption itself, the filesystem is intact but 32 MB short. Give it back:
sudo mount /dev/nvme0n1p6 /mnt
sudo btrfs filesystem resize max /mnt
sudo umount /mntThe system boots normally again. Nothing was lost.
Encryption was interrupted
Power loss, a closed lid, a killed terminal. LUKS2 re-encryption is journaled with checksum resilience precisely for this — it can pick up where it stopped.
The easy way: just re-run luks-deploy.sh. It reads the LUKS2
online-reencrypt requirement flag from the header, offers to resume, finishes
the encryption with cryptsetup reencrypt --resume-only, and then runs the
whole configuration + verification phase as if nothing had happened. You will
be asked for the passphrase you set.
By hand, the resume step alone is:
sudo cryptsetup reencrypt --resume-only /dev/nvme0n1p6If resume reports no re-encryption in progress but the header is valid, the data phase finished and only the config steps are missing → next section.
Encrypted fine, but it will not boot
The container is good; something in the boot chain does not know about it.
The easy way: just re-run luks-deploy.sh. When it finds a complete LUKS
header on the selected root, it offers a configuration-only mode: it unlocks
the container, redoes every config step (crypttab, fstab, kernel cmdline, GRUB
defaults, BLS entries, dracut config, all initramfs images — all idempotent) and
re-runs the full verification gate. No data is touched.
To do the same by hand instead: open, mount, chroot, and repair.
# 1. Open the container
sudo cryptsetup open /dev/nvme0n1p6 fedora_crypt
# 2. Confirm the filesystem inside is intact
sudo blkid /dev/mapper/fedora_crypt # → TYPE="btrfs"
# 3. Mount root (use the subvol from your fstab — usually 'root')
sudo mount -o subvol=root /dev/mapper/fedora_crypt /mnt
# 4. Mount the rest
sudo mount /dev/nvme0n1p5 /mnt/boot
sudo mount /dev/nvme0n1p4 /mnt/boot/efi
for i in dev dev/pts proc sys run; do sudo mount --bind "/$i" "/mnt/$i"; done
# 5. Chroot
sudo chroot /mnt /bin/bashInside the chroot, check each of the five things that must be right:
LUKS_UUID=$(cryptsetup luksUUID /dev/nvme0n1p6)
echo "LUKS UUID: $LUKS_UUID"
cat /etc/crypttab # → fedora_crypt UUID=<LUKS_UUID> none luks,discard
cat /etc/fstab # → / and /home on /dev/mapper/fedora_crypt
cat /etc/kernel/cmdline # → contains rd.luks.uuid= and rd.luks.name=
grep rd.luks /boot/loader/entries/*.conf # → EVERY entry has both
cat /etc/dracut.conf.d/99-luks.conf # → add_dracutmodules+=" crypt dm btrfs "Fix whatever is missing:
# crypttab
echo "fedora_crypt UUID=$LUKS_UUID none luks,discard" >> /etc/crypttab
# kernel cmdline (source of truth for future kernel installs)
echo " rd.luks.uuid=$LUKS_UUID rd.luks.name=$LUKS_UUID=fedora_crypt" >> /etc/kernel/cmdline
# dracut modules
echo 'add_dracutmodules+=" crypt dm btrfs "' > /etc/dracut.conf.d/99-luks.conf
# rebuild every initramfs
dracut --regenerate-all --force
# update every BLS entry
grubby --update-kernel=ALL \
--args="rd.luks.uuid=$LUKS_UUID rd.luks.name=$LUKS_UUID=fedora_crypt"
# regenerate the real grub.cfg — note the /boot path, NOT the ESP path
grub2-mkconfig -o /boot/grub2/grub.cfgThen exit, unmount, reboot:
exit
sudo umount -R /mnt
sudo cryptsetup close fedora_crypt
sudo rebootThe two mistakes that cause most non-booting systems
-
rd.luks.namemissing.rd.luks.uuidalone creates/dev/mapper/luks-<UUID>, but fstab says/dev/mapper/fedora_crypt. The names do not match, root never mounts. You need both parameters. -
BLS entries not updated. Fedora uses Boot Loader Specification entries.
Editing
/etc/default/gruband runninggrub2-mkconfigdoes not touch/boot/loader/entries/*.conf. Usegrubby --update-kernel=ALL.
First boot fails with SELinux denials
Files written from the live environment (crypttab, the dracut conf, edited
fstab) can end up mislabeled — the live system's policy did the labeling, not
the target's. luks-deploy.sh runs restorecon on everything it touched from
inside the chroot, but if you edited files by hand during a manual repair, the
boot can still die on denials (root mounts, then systemd units fail en masse,
or the boot hangs after the passphrase).
Fix: at the GRUB menu, press e, append enforcing=0 to the linux line, and
boot once. Then relabel and re-enable:
sudo restorecon -RFv /etc /boot
sudo setenforce 1Then reboot normally. (For a full relabel instead: sudo touch /.autorelabel && sudo reboot — takes a few minutes on first boot.)
Corrupt or missing LUKS header
The header is 16 MB at the start of the partition holding your key slots. Without it the data is undecryptable — which is why this tooling backs it up in three places.
Find a backup:
ls /boot/luks-header-backup.img # written by luks-deploy
ls /root/LUKS-RECOVERY-*/luks-header-*.img # the recovery bundle
ls <live-usb>/pre-luks-state-*/luks-header-backup.imgRestore it:
sudo cryptsetup luksHeaderRestore /dev/nvme0n1p6 \
--header-backup-file /boot/luks-header-backup.imgA restored header restores the key slots as they were when it was backed up. If you changed your passphrase since, the old passphrase is what works now.
GRUB rescue> prompt — the ESP stub was overwritten
Almost always caused by running grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg.
On Asahi that file must stay a small chainload stub, not a full config.
From the live USB, mount the EFI partition and restore the stub by hand:
sudo mount /dev/nvme0n1p4 /mnt/efi
sudo mount /dev/nvme0n1p5 /mnt/boot # to read the /boot UUID
BOOT_UUID=$(blkid -s UUID -o value /dev/nvme0n1p5)
sudo tee /mnt/efi/EFI/fedora/grub.cfg >/dev/null <<STUB
search --no-floppy --root-dev-only --fs-uuid --set=dev $BOOT_UUID
set prefix=(\$dev)/grub2
export \$prefix
configfile \$prefix/grub.cfg
STUB
sudo syncInstall boot-guards/ afterwards so it cannot happen again.
Passphrase change
If you mistyped during luksFormat and want to change it, pair the change with
the same KDF flags — otherwise cryptsetup silently reverts that keyslot to
its benchmarked defaults (sha256, machine-dependent memory):
sudo cryptsetup luksChangeKey /dev/nvme0n1p6 \
--pbkdf argon2id \
--pbkdf-memory 4194304 \
--pbkdf-force-iterations 10 \
--pbkdf-parallel 4 \
--hash sha512Verify afterwards with cryptsetup luksDump, and take a fresh header backup —
your old backup no longer matches the current key slots.
Emergency: get the data out without fixing the boot
If you only need your files back:
sudo cryptsetup open /dev/nvme0n1p6 fedora_crypt
sudo mount -o subvol=home /dev/mapper/fedora_crypt /mnt
# copy /mnt somewhere else, then:
sudo umount /mnt && sudo cryptsetup close fedora_cryptMount with -o subvolid=5 instead to see the top level with every subvolume.
Nothing here worked
You cannot brick the Mac — Apple Silicon DFU / System Recovery always works, and macOS is on separate APFS partitions this tooling never touches. Worst case you reinstall Fedora Asahi and restore from the backup you took in Step 2.
When asking for help, include:
sudo cryptsetup luksDump /dev/nvme0n1p6 | head -30
cat /etc/crypttab /etc/fstab /etc/kernel/cmdline
grep options /boot/loader/entries/*.confplus the luks-deploy-*.log from the run.
← Back to the full guide: encrypt Fedora Asahi Remix with LUKS2, in place