LinuxLXXX · Common Failure ScenariosCommon failures
Failure: a service will not start, a host will not boot
What you'll learn
- Read a unit failure from Result= and ExecMainStatus= rather than from guesswork
- Separate a service that never started from one that started and died
- Diagnose a boot that stops in the initramfs from one that stops at emergency.target
- Recognise the latent-failure pattern where a reboot only reveals a change made weeks earlier
Prerequisites
Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-11
“It will not start” is the most common ticket in Linux operations and the one most often answered with a guess. The methodology says form a falsifiable hypothesis. This lesson gives you the evidence that lets you form one in under a minute.
First split: never started, or started and died?
These are different failures with different evidence, and
systemd tells you which one you have without any
interpretation:
$ systemctl show myapp.service -p Result -p ExecMainStatus -p ExecMainCode -p NRestarts -p ActiveEnterTimestampResult=exit-code
ExecMainStatus=1
ExecMainCode=1
NRestarts=5
ActiveEnterTimestamp=Mon 2026-08-10 03:14:02 UTCIllustrative output
ActiveEnterTimestamp is the discriminator. If it is empty,
the unit has never reached active state in this boot: the
failure is at start. If it holds a timestamp and NRestarts
is climbing, the service starts fine and then dies - a
completely different investigation, usually resources or a
crash on first request.
Result= names the class of failure:
Result= | Meaning | Where to look next |
|---|---|---|
exit-code | The process ran and exited non-zero | Application log, ExecMainStatus |
signal | The kernel or something else killed it | dmesg -T, OOM killer, SIGSEGV |
timeout | It did not signal readiness in time | Type= mismatch, slow dependency |
protocol | It exited without the expected notification | Type=notify without sd_notify |
start-limit-hit | systemd gave up restarting it | The earlier failures, not this one |
core-dump | It crashed | coredumpctl info |
The four failures behind Result=exit-code
Almost every start failure that reaches a queue is one of four things, and each has a fingerprint:
- Config syntax - the daemon exits within milliseconds and prints a line number. Validate with the daemon own checker (nginx -t, sshd -t, named-checkconf) before blaming systemd.
- Address already in use - the log says EADDRINUSE or bind(). Find the holder with ss -tlnp; it is frequently the previous instance that never exited.
- Permission denied - the path exists and the user cannot read it. Check the unit User=, the file mode, and then the MAC layer: dmesg for AVC denials, or journalctl -t audit.
- Missing dependency - the daemon starts before the thing it needs. The unit needs After= and Requires=, not a sleep.
The difference between a permission problem and a mandatory access control denial matters, because the file permissions look correct in the second case:
$ journalctl -b -k | grep -iE 'avc:|apparmor=' | tailaudit: type=1400 audit(1754870042.881:112): avc: denied { read } for pid=2211 comm="nginx" name="app.conf" dev="dm-0" ino=131842 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0Illustrative output
ls -l shows mode 0644 and the operator concludes the
permissions are fine. They are. The label is wrong.
When the host will not boot
The same split applies: did it fail before or after the root filesystem was mounted? The screen tells you which.
- An
(initramfs)prompt means the root device was never found. The cause is upstream of the OS: a changed disk name or UUID, a missing storage module in the initramfs, an unassembled RAID array, an unactivated LVM volume group.blkidandlsblkfrom that prompt are your evidence. - An “emergency mode” prompt with a working journal means
the root filesystem mounted and something later failed. That
is almost always
/etc/fstab: a non-existent device, a wrong UUID or a filesystem that will not fsck.
From an emergency shell the evidence is one command:
# journalctl -b -p err --no-pager; systemctl --failed --no-pagersystemd[1]: Failed to mount /data.
systemd[1]: Dependency failed for Local File Systems.
UNIT LOAD ACTIVE SUB DESCRIPTION
* data.mount loaded failed failed /dataIllustrative output
The failing unit names the failing mount, and the mount names the fstab line. Test a repaired fstab before the next reboot:
findmnt --verify --verbose # parse and sanity-check /etc/fstab
mount -a # apply it now, in a state you can undo
Two habits remove most boot incidents entirely. Mount
non-essential filesystems nofail so a missing data volume
degrades the host instead of stopping the boot, and use
UUID= rather than /dev/sdb1, which is not a stable name.
Knowledge check
Knowledge check · 5 questions
Q1. `systemctl show` reports `Result=start-limit-hit`. What have you learned about the fault?
Q2. A daemon fails to open its config file. `ls -l` shows mode 0644 owned by root, and the unit runs as root. What is the next check?
Q3. A host stops at an `(initramfs)` prompt after a reboot. Which explanation is consistent with that evidence?
Q4. A host that boots into emergency mode after a routine patch reboot was broken by that patch.
Q5. Which pieces of evidence separate "never started" from "started and then died"? Select all that apply.
Passing score: 75%. Answers are checked in this browser.