Skip to content
LinuxFix Published Updated 4 min readViews unavailable

Fixing a Broken GRUB2 Configuration After a Failed Update

A kernel update leaves the system unable to boot into any menu entry — how to regenerate a working GRUB2 configuration from a rescue environment.

A GRUB2 configuration corrupted by an interrupted update — or one that simply references a kernel/initrd pair that no longer exists — needs to be regenerated from a working environment, not hand-edited entry by entry.

Step 1: boot from a live USB/rescue image

Any Linux live environment matching your system’s architecture works for the repair steps below.

Step 2: identify and mount your root partition

lsblk
mount /dev/sda2 /mnt
mount /dev/sda1 /mnt/boot/efi   # if using UEFI with a separate ESP

Step 3: chroot into the installed system

for d in dev proc sys; do mount --bind /$d /mnt/$d; done
chroot /mnt /bin/bash

This makes the installed system’s own tools (its specific GRUB version, its specific kernel packages) the ones doing the repair, rather than mismatched tools from the live environment.

Step 4: regenerate the GRUB configuration

grub-mkconfig -o /boot/grub/grub.cfg

On Debian/Ubuntu-based systems, update-grub is a wrapper around the same command.

Step 5: reinstall the GRUB bootloader itself

grub-install /dev/sda

For UEFI systems, this instead targets the EFI System Partition rather than a disk device directly — confirm you’re using the correct invocation for BIOS vs. UEFI boot mode.

Step 6: verify the configuration actually lists valid kernels

grep -A1 "menuentry" /boot/grub/grub.cfg | grep vmlinuz
ls /boot/vmlinuz-*

Confirm every kernel referenced in the generated config file actually exists on disk — a config referencing a removed kernel version means the underlying package state, not GRUB itself, needs cleanup first.

Step 7: clean up orphaned kernel packages if that’s the underlying cause

dpkg --list | grep linux-image     # Debian/Ubuntu
rpm -qa | grep kernel               # RHEL/Fedora

Remove genuinely orphaned old kernel packages, then regenerate the GRUB config again — this prevents the same broken-reference problem from recurring.

Step 8: exit the chroot and reboot

exit
umount -R /mnt
reboot

Why regenerating beats hand-editing grub.cfg

grub.cfg is an auto-generated file, built from templates in /etc/grub.d/ and the actual installed kernel packages — hand-editing it directly fixes the symptom for exactly one boot, since any future kernel update or grub-mkconfig run overwrites your manual changes. Fixing the underlying package state and regenerating properly is the only change that survives the next update.

Step 9: restore missing dual-boot entries with os-prober

apt install os-prober            # if not already present
os-prober
grub-mkconfig -o /boot/grub/grub.cfg

If a dual-boot system’s regenerated grub.cfg only lists Linux kernels and the other operating system’s entry has disappeared, os-prober is the specific component responsible for detecting other installed operating systems and generating their menu entries — some distributions disable it by default for security reasons (a mounted, untrusted partition being scanned), and some GRUB builds simply don’t invoke it unless GRUB_DISABLE_OS_PROBER=false is explicitly set in /etc/default/grub first. Confirming os-prober actually detects the other OS’s partition (os-prober run standalone prints what it found) before regenerating the config isolates whether the problem is detection or generation.

Step 10: don’t skip this on a Secure Boot system

mokutil --sb-state

On a system with UEFI Secure Boot enabled, GRUB is launched through a signed shim binary that verifies GRUB’s own signature before handing off control — reinstalling GRUB (grub-install) on such a system needs to target the correct signed binary path, and a custom or self-compiled kernel needs to be signed and enrolled via mokutil, or Secure Boot will refuse to boot it even after an otherwise-correct GRUB repair. Confirming Secure Boot’s actual state with mokutil --sb-state before troubleshooting further avoids mistaking a signature-verification refusal for a plain GRUB configuration problem — they present similarly at first boot, but need entirely different fixes.

Why grub-mkconfig itself sometimes fails outright rather than producing a bad config

grub-mkconfig isn’t a single monolithic program — it runs each numbered script in /etc/grub.d/ in sequence (10_linux for standard kernel entries, 30_os-prober for other operating systems, and so on) and concatenates their output. A single misbehaving or corrupted script in that directory — one left in a half-updated state by an interrupted package upgrade, or a custom script a previous administrator added and never finished — can make the entire grub-mkconfig run fail or exit early, rather than merely omitting that one script’s own contribution. Running each script individually (sh -x /etc/grub.d/10_linux) isolates exactly which one is actually erroring, which is considerably faster than debugging the full concatenated output when only one specific stage in the pipeline is the real problem.

Related:

Sources:

Comments