Skip to content

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

lsblk -f
  • EFI — vfat, small (~100–500MB)
  • boot — ext4, unencrypted
  • root — type crypto_LUKS

2. Unlock and mount

sudo cryptsetup luksOpen /dev/sdX3 cryptroot   # any temporary name; enter passphrase

Note: A WARNING: target 'cryptroot' not found in /etc/crypttab here is harmless — the live session's crypttab is empty and irrelevant. It only matters later, during update-initramfs (see steps 5 and 8).

If LVM-on-LUKS:

sudo lvscan
sudo vgchange -ay

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:

cat /etc/crypttab
blkid /dev/sdX3     # LUKS container UUID — must match the UUID= in crypttab

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

apt update
apt --fix-broken install

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 install plus 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

update-initramfs -c -k all

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-initramfs output), not $(uname -r) — inside a chroot, uname -r still reports the live USB's running kernel, not the installed one.

b) grub.cfg references the right UUIDs:

grep -E "linux|cryptdevice" /boot/grub/grub.cfg | head
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:

ls /boot/efi/EFI/ubuntu/
efibootmgr -v
Expect grubx64.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:

cat /etc/fstab
blkid /dev/sdX1   # EFI partition
blkid /dev/sdX2   # boot partition

/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:

nano /etc/fstab   # correct the UUID= value on the mismatched line
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

exit   # leave chroot
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:

sudo fuser -vm /mnt/whatever

12. Reboot

sudo 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