06 · Troubleshooting Boot Failures & Recovery Mode¶
The best time to diagnose a boot failure is before it happens — most of the classic causes (a bad fstab entry,
a service that blocks on a dependency that will never arrive) are testable on a running system without ever
risking an actual failed boot. This lesson tests the single most common one directly, and lays out what
rescue/emergency targets actually are for the cases that do slip through.
Worked example: catching a broken fstab entry before it ever causes a boot failure¶
$ sudo cp /etc/fstab /tmp/fstab.bak
$ echo "/dev/nonexistent /mnt/broken ext4 defaults 0 2" | sudo tee -a /etc/fstab
$ sudo mount -a
mount: /mnt/broken: mount point does not exist.
dmesg(1) may have more information after failed mount system call.
$ sudo cp /tmp/fstab.bak /etc/fstab
(Real output from this course's lab VM.) mount -a reads /etc/fstab and attempts every entry exactly as boot
would, without rebooting — this is the single most direct way to validate a new fstab line before trusting
it to a reboot, and it caught a real problem immediately: in this case the mount point didn't even exist yet
(a second, equally common failure mode alongside "the device doesn't exist" — both are worth testing for, since
mkdir -p on the mount point is sometimes the only thing missing). A bad fstab entry for a non-root
filesystem, left uncaught and hit during an actual boot, is exactly the scenario that drops a system into an
emergency shell — systemd can't reach the target that depends on that failed mount, and rather than
silently continuing in a broken state, it stops and asks a human to intervene.
Worked example: what rescue.target actually pulls in¶
$ systemctl list-dependencies rescue.target --no-pager | head -n6
rescue.target
○ ├─grub-initrd-fallback.service
○ ├─rescue.service
● └─sysinit.target
● ├─apparmor.service
● ├─blk-availability.service
$ journalctl --list-boots --no-pager
IDX BOOT ID FIRST ENTRY LAST ENTRY
0 1e8b72759fec45ccae08682c99b4d38f Thu 2026-10-22 23:26:05 IST Sat 2026-10-24 16:37:25 IST
(Real output — this VM has only ever had one boot so far, which is itself realistic for a lab environment created
recently; journalctl --list-boots is exactly the command to check for more boots, and is honest about there
being only one here rather than fabricating a prior failed boot to show.) rescue.target depends on
sysinit.target (early boot-critical units: device setup, security modules, basic filesystem mounts) but
not on multi-user.target or anything beyond it — by design, rescue mode brings up just enough of the
system to get a working root shell and basic diagnostic tools, deliberately skipping network services, display
managers, and anything that might itself be the cause of the boot problem you're trying to diagnose. emergency.
target (not shown here, but worth knowing) goes even further, skipping even most of sysinit.target — the
right choice when the filesystem itself, not just a later service, might be suspect.
How It Actually Works¶
mount -a's guarantee of accuracy comes from the fact that it's not a separate simulation — it's the exact same
mount() syscall path and the exact same /etc/fstab parsing that real boot-time mounting uses, just invoked
interactively instead of by systemd's generated mount units. This is why testing with mount -a genuinely
predicts what boot would do, rather than approximating it.
When a systemd-managed boot genuinely can't satisfy a unit's requirements (a .mount unit failing because its
device or mount point is missing, as reproduced above but imagine uncaught), and something else in the
dependency graph (Level 2, Lesson 6) strictly Requires= that unit, systemd doesn't simply skip ahead and
pretend everything's fine — it drops to a target with the problem unit's chain already satisfied as far as
possible and stops there, typically emergency mode for a root-filesystem-level problem or an interactive
prompt for a specific failed non-critical mount, giving a human the chance to fix /etc/fstab, re-run systemctl
daemon-reload, and continue booting rather than ending up with a half-started system silently missing
something it depended on.
Common mistakes¶
- Rebooting immediately after editing
/etc/fstabwithout testing withmount -afirst. As this lesson demonstrates directly, the exact same failuremount -awould have caught instantly, interactively, with full context, instead surfaces during boot — at a point with far less context and a much higher cost to get wrong. - Panicking at an emergency shell and immediately trying destructive fixes. The emergency shell is a
genuinely safe place to investigate first —
journalctl -xb(this boot's full log) almost always names the specific unit and reason directly; fixing the named cause and runningsystemctl defaultto continue booting is usually faster and safer than guessing. - Forgetting that
nofailexists for genuinely optional mounts. Adding thenofailoption to anfstabentry for a non-critical filesystem (a removable drive, an optional network share) tellssystemdnot to block the rest of boot if that one mount fails — appropriate for "nice to have," wrong for anything the system actually needs to function.
Exercise¶
Add a deliberately broken line to a copy of your /etc/fstab (never test this against the real file without
a backup, exactly as this lesson did), and run mount -a against it to confirm the failure is caught. Then run
systemctl list-dependencies rescue.target and systemctl list-dependencies emergency.target side by side, and
identify at least one unit present in one target's dependency list but not the other's, explaining what that
difference implies about which boot problems each target is meant to help diagnose.