Real World Example of Failed Service
Every tool covered across this section works cleanly in isolation. Real failures rarely announce themselves that neatly — a service just says “failed,” a system drops into a shell you didn’t expect, a scheduled job silently never ran. This chapter walks through several genuinely common failure scenarios, pulling together tools from across this entire section, then closes with a troubleshooting flow and a final best-practices recap.
Scenario 1: A Service Won’t Start
sudo systemctl start myappJob for myapp.service failed because the control process exited with error code.
See "systemctl status myapp.service" and "journalctl -xeu myapp.service" for details.Follow exactly what it suggests:
systemctl status myapp
journalctl -u myapp -n 50A few of the most common underlying causes, roughly in order of how often they actually turn out to be the culprit:
- Wrong path in
ExecStart=— a typo, or a binary that simply isn’t at the path specified. The journal entry will typically say something direct like “No such file or directory.” - Permission problem — if the unit specifies
User=, that account may not have permission to read a config file, write to a log directory, or execute the binary at all. Cross-check with the permission-reading skills from earlier in this course —ls -lon whatever the service is trying to access, and confirm the specified user genuinely has the access it needs. - Port already in use — for anything binding to a network port, another process may already be holding it.
lsof -i :<port>identifies exactly what, the same way it would for any other “address already in use” situation. - A missing dependency — if the unit specifies
Requires=orAfter=on something that itself failed to start, this service never gets a chance to start at all.systemctl statuson the dependency itself will usually reveal this directly.
sudo systemd-analyze verify /etc/systemd/system/myapp.serviceWorth running early in this process, not as a last resort — it catches outright syntax problems in the unit file itself before you go looking for a more complicated explanation.
Scenario 2: A Service Starts, Then Immediately Crashes On Loop
systemctl status myappActive: activating (auto-restart) (Result: exit-code) since ...activating (auto-restart) is the tell — this is Restart=on-failure doing exactly what it’s configured to do, repeatedly, because the underlying program keeps exiting with a failure status moments after starting. Watch it happen live:
journalctl -u myapp -fThis is genuinely one of the more useful moments to use -f — watching each restart attempt and its immediate failure in real time, rather than piecing it together from a static log after the fact, often makes an intermittent or timing-related cause far more obvious than it would be scrolling through history.
If the crash loop itself is generating overwhelming log volume, temporarily stop the cycle to investigate calmly:
sudo systemctl stop myappStopping breaks the restart loop entirely, letting you run the underlying program manually, directly, to see its actual error output without systemd restarting it out from under you every few seconds.
Scenario 3: The System Boots Into Emergency Or Rescue Mode
You reboot a system, and instead of a normal login, you’re dropped into a minimal recovery shell. First, understand why:
journalctl -bScan for failures — a service or mount that failed early enough in the boot sequence to prevent the default target from ever being reached. One of the most common real causes: a bad /etc/fstab entry — exactly the failure mode warned about in this course’s storage material. A typo in a UUID, a filesystem type that doesn’t match what’s actually on the partition, or a device that’s no longer present will each cause the corresponding mount to fail, and systemd treats an unmountable filesystem listed in fstab as serious enough to block normal boot entirely, dropping to an emergency shell instead of silently continuing without it.
The fix, from inside that recovery shell:
nano /etc/fstabComment out or correct the problematic line, then test before rebooting again — this is precisely the discipline emphasized when /etc/fstab was first introduced:
mount -aIf that succeeds cleanly, reboot normally and confirm the system comes up as expected.
Scenario 4: A cron Job That Silently Never Runs
Nothing crashes here — there’s just no evidence the job ever executed at all. Start by confirming it’s actually scheduled the way you expect:
crontab -lThen check whether cron itself even attempted to fire it:
grep CRON /var/log/syslogIf there’s no entry at all for the expected time, the schedule syntax itself is likely wrong, or the crontab was never saved correctly. If there is an entry showing cron fired the job, but nothing seems to have actually happened, the far more common cause is the minimal-environment problem — a script relying on a command that isn’t found under cron’s stripped-down PATH, failing silently the moment it hits that missing command. Test this theory directly by running the exact same command cron would, using env -i to simulate a similarly bare environment:
env -i /home/you/scripts/backup.shIf this fails the same way, the fix is exactly what the cron chapter covered — absolute paths inside the script, or an explicit PATH= line at the top of the crontab.
Scenario 5: “I Edited The Unit File, But Nothing Changed”
The most common cause of this specific complaint, worth restating here because it’s genuinely easy to forget in the moment: systemd caches unit file contents at load time and doesn’t notice edits to the file on disk automatically.
sudo systemctl daemon-reload
sudo systemctl restart myappIf a restart alone doesn’t pick up the change, the reload step was very likely the missing piece.
A Troubleshooting Flow
flowchart TD
A["Something's wrong with a service or boot"] --> B{"systemctl status<br/>shows failed?"}
B -->|"Yes"| C["journalctl -u <unit> -n 50"]
C --> D{"Crash-looping<br/>(auto-restart)?"}
D -->|"Yes"| E["journalctl -u <unit> -f<br/>watch it happen live"]
D -->|"No"| F["Check ExecStart path,<br/>permissions, port conflicts"]
B -->|"No, boot itself failed"| G["journalctl -b<br/>find what blocked the default target"]
G --> H["Often: a bad /etc/fstab entry"]
A --> I{"A scheduled job<br/>never ran?"}
I -->|"Yes"| J["grep CRON /var/log/syslog"]
J --> K["Test with env -i<br/>to catch PATH issues"]
Final Best Practices Recap
- Always follow up a failure with
journalctl -u <unit>, not justsystemctl status’s truncated preview — the full context is very often there. daemon-reloadafter every unit file edit, without exception — make it reflexive rather than something you remember only after confusion sets in.- Validate unit files with
systemd-analyze verifybefore relying on them, the same waymount -avalidates anfstabedit before trusting it to survive a reboot. - Use absolute paths everywhere in both unit files and cron jobs — the single most common cause of “it works when I run it myself” across both.
- Log cron output somewhere real, rather than discarding it — a silently failing scheduled task is far harder to catch than one leaving a trail.
journalctl -b -1is your best friend after an unexpected reboot — assuming persistent journal storage is actually configured, which is worth confirming on any system you’re responsible for before you actually need it.