Repairing Boot on an Encrypted Secure-Boot Ubuntu System¶
Published July 7, 2026
Written with Claude
Scenario: UEFI system, Secure Boot enabled, one disk with EFI + boot + LUKS-encrypted root partitions, booting from a live USB to repair GRUB/initramfs/NVRAM.
0. Confirm the live session is in UEFI mode¶
[ -d /sys/firmware/efi ] && echo "UEFI - good" || echo "Legacy mode - reboot the USB via UEFI boot entry"
If this fails, reboot and pick the UEFI-labeled entry for the USB in the firmware boot menu. Nothing below works in legacy/CSM mode.
1. Identify partitions¶
- EFI — vfat, small (~100–500MB)
- boot — ext4, unencrypted
- root — type
crypto_LUKS
2. Unlock and mount¶
Note: A
WARNING: target 'cryptroot' not found in /etc/crypttabhere is harmless — the live session's crypttab is empty and irrelevant. It only matters later, duringupdate-initramfs(see steps 5 and 8).
If LVM-on-LUKS:
Mount everything:
sudo mount /dev/mapper/cryptroot /mnt # or the VG's root LV
sudo mount /dev/sdX2 /mnt/boot
sudo mount /dev/sdX1 /mnt/boot/efi
3. Bind mounts for chroot — efivars is the critical one¶
for d in dev dev/pts proc sys run; do sudo mount --bind /$d /mnt/$d; done
sudo mount --bind /sys/firmware/efi/efivars /mnt/sys/firmware/efi/efivars
efivarfs is a separate mount underneath /sys, not carried in by a plain bind of /sys. Skip this line and grub-install/efibootmgr will silently fail to write the NVRAM boot entry — everything else looks fine, but the firmware still can't find the OS on next boot.
4. Chroot in¶
sudo chroot /mnt /bin/bash
export HOME=/root LC_ALL=C
ls /sys/firmware/efi/efivars | wc -l # want hundreds, not 0
5. Match the LUKS mapper name to the real crypttab¶
Ubuntu commonly auto-names the mapper luks-<LUKS-container-UUID>. Check what the installed system actually expects before rebuilding the initramfs:
If the name you opened with (cryptroot) doesn't match the crypttab's target name, close and reopen with the correct name:
exit
sudo umount -R /mnt
sudo cryptsetup luksClose cryptroot
sudo cryptsetup luksOpen /dev/sdX3 luks-<container-uuid>
...then redo the mounts/binds/chroot from steps 2–4 with the corrected name.
6. Fix broken packages, then purge & reinstall kernel packages¶
Run this first if apt/dpkg reports any half-configured or unmet-dependency packages. Trying to reinstall grub/kernel packages on top of a broken package state just produces more broken state.
If the kernel install itself looks suspect (missing files, mismatched headers, boot failures with no other explanation), purge everything kernel-related and reinstall clean:
dpkg -l | grep -E "linux-image|linux-headers|linux-modules" # see what's currently installed
apt purge --autoremove $(dpkg -l | grep -E '^ii linux-(image|headers|modules)' | awk '{print $2}')
apt install --reinstall linux-image-generic linux-headers-generic
The purge removes every kernel image/headers/modules package found; the reinstall pulls the current -generic metapackages back down, which in turn pull in the specific versioned image/headers packages and automatically trigger update-initramfs/update-grub via their postinst hooks. This is safe to run from the chroot — you're never removing the kernel that's actually running (that's still the live USB's kernel, unaffected by anything happening inside /mnt).
Only do the purge/reinstall if you suspect actual kernel package corruption. For a routine boot repair,
apt --fix-broken installplus steps 7–8 below are usually all you need.
7. Reinstall the boot chain (Secure Boot signed binaries)¶
apt install --reinstall grub-efi-amd64-bin grub-efi-amd64-signed shim-signed
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ubuntu --recheck --uefi-secure-boot
update-grub
Reinstalling shim-signed / grub-efi-amd64-signed matters — these are the Microsoft-signed binaries. A bare grub-install alone can leave you with an unsigned GRUB that Secure Boot rejects.
Debian/Ubuntu's grub-install also accepts --uefi-secure-boot (and --no-uefi-secure-boot), which forces installation of the Secure Boot-aware shim chain regardless of whether grub-install auto-detects Secure Boot as currently enabled. Useful when running from a live session where detection can be unreliable — it removes the guesswork.
8. Rebuild initramfs¶
Should complete with no crypttab warning now that the mapper name matches. (Skip this if step 6's kernel reinstall already triggered it automatically — rerunning is harmless either way.)
9. Verify everything before rebooting¶
a) Initramfs actually has the unlock config:
cat main/cryptroot/crypttab # after: unmkinitramfs /boot/initrd.img-<version> /tmp/initrd-check (from that dir)
Use the actual installed kernel version here (e.g. from the
update-initramfsoutput), not$(uname -r)— inside a chroot,uname -rstill reports the live USB's running kernel, not the installed one.
b) grub.cfg references the right UUIDs:
Three UUIDs are in play — don't confuse them:| Where it appears | What it is | Verify against |
|---|---|---|
cryptdevice=UUID=... |
LUKS container UUID | blkid /dev/sdX3 |
final root=UUID=... / root=/dev/mapper/luks-... |
decrypted filesystem UUID | blkid /dev/mapper/luks-<uuid> |
/etc/crypttab UUID=... |
LUKS container UUID (same as cryptdevice) | blkid /dev/sdX3 |
(No cryptomount line in grub.cfg is normal here — since /boot is unencrypted, GRUB never decrypts anything itself; that's the initramfs's job via cryptdevice=.)
c) EFI binaries and NVRAM entry:
Expectgrubx64.efi, shimx64.efi, mmx64.efi, BOOTX64.CSV, and an efibootmgr entry named ubuntu pointing at \EFI\ubuntu\shimx64.efi, present in BootOrder (ideally first).
d) fstab UUIDs match reality:
/etc/fstab will have lines roughly like:
UUID=xxxx-xxxx /boot/efi vfat umask=0077 0 1
UUID=yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy /boot ext4 defaults 0 2
Match each by mount point, not by position in the file:
- The line mounted at /boot/efi → UUID must equal blkid /dev/sdX1 (short-form UUID, since it's vfat)
- The line mounted at /boot → UUID must equal blkid /dev/sdX2
If either differs — common after a partition was recreated, resized, or reformatted rather than just repaired — fix it directly in fstab before rebooting:
A stale UUID here won't stop GRUB from loading (it doesn't read fstab), but it will cause the boot/EFI partition to fail mounting once the kernel hands off to the real init system, even though everything up to that point looked fine.10. Delete fbx64.efi from the EFI partition¶
On some firmware, leaving fbx64.efi (shim's fallback loader, installed by shim-signed alongside grubx64.efi/shimx64.efi) in place causes a boot loop once the real NVRAM entry exists — the firmware keeps re-triggering the fallback path instead of using the normal entry. Once the ubuntu NVRAM entry is confirmed working (step 9c), remove it:
find /boot/efi -iname "fbx64.efi"
sudo rm /boot/efi/EFI/ubuntu/fbx64.efi # adjust path to whatever find reported
This is safe to remove after the real boot entry is confirmed — it's only a fallback discovery mechanism, not something the normal boot path depends on.
11. Clean unmount¶
sudo umount /mnt/sys/firmware/efi/efivars
sudo umount -R /mnt/sys
sudo umount -R /mnt/run
sudo umount -R /mnt/proc
sudo umount -R /mnt/dev
sudo umount /mnt/boot/efi
sudo umount /mnt/boot
sudo umount /mnt
sudo cryptsetup luksClose luks-<container-uuid>
If anything reports "busy," check what's holding it before forcing:
12. Reboot¶
Remove the live USB as it restarts. Once back in the installed system, run sudo update-grub once more from live hardware (not chroot) as a final sanity pass.
Quick troubleshooting index¶
| Symptom | Likely cause | Where to look |
|---|---|---|
luksOpen warns about crypttab |
Harmless — live session's crypttab is irrelevant | Ignore during unlock |
update-initramfs warns about crypttab |
Mapper name ≠ crypttab target name | Step 5 |
apt/dpkg errors, half-configured packages |
Broken package state | Step 6 |
| Kernel files missing/mismatched, unexplained boot failure | Kernel package corruption | Step 6 |
| Boots to GRUB but not further | UUID mismatch (LUKS container vs. decrypted fs vs. fstab) | Step 9b/9d |
| GRUB never appears / firmware skips it | Missing/broken NVRAM entry (often from missing efivars bind mount) | Steps 3, 9c |
| Boot loop after everything looks correct | Leftover fbx64.efi fallback loader |
Step 10 |
| Unsigned GRUB rejected by Secure Boot | Only ran grub-install, skipped shim-signed/grub-efi-amd64-signed reinstall |
Step 7 |