Decode the whole systemctl status output
The systemctl status Explainer reads pasted systemctl status or journalctl -u output and names the cause, including start-limit-hit, crash loops, timeouts and OOM kills. Nothing is uploaded.
The service crashed, systemd restarted it four times in half a second, and now systemctl start refuses outright. The usual fix on forums is to raise StartLimitBurst, which makes the same crash loop run longer before it stops. The limit did its job. What it hid is the error the program printed five times before it tripped.
What Does start-limit-hit Look Like?
Reproduced on 2026-10-10 on this machine (Kali, systemd 261) with a throwaway user unit: ExecStart= prints cannot bind 127.0.0.1:8099: address in use to stderr and exits 1, with Restart=on-failure and nothing else set. The first systemctl --user start returned 0. Three seconds later:
Every log line in that view is systemd's. The program's cannot bind message, the actual problem, is not on screen. And the service is now parked:
Why Did It Trip So Fast?
The defaults, read from the unit with systemctl show, are StartLimitBurst=5, StartLimitIntervalSec=10s and RestartSec=100ms. Every automatic restart counts as a start. A program that dies immediately therefore restarts every ~100 ms and spends its five starts in about half a second, well inside the 10-second window. Any service with Restart= and a startup bug will hit the limit this way, and that is intended: without it, the loop would never stop.
How Do I Fix It?
- Read the program's error.
journalctl -u UNIT -n 50(with--userfor a user unit) goes back past systemd's lines. Here it was the port. Fix that first; nothing else on this page matters until the program can start. - Clear the counter.
systemctl reset-failed UNIT && systemctl start UNIT. The counter does not reset when you edit the unit or rundaemon-reload. - Space the restarts in
[Service], so that a transient failure (a database that is not up yet) gets retried over a meaningful window:
With those values, five restarts take 15 seconds, longer than the 10-second window, so the limit never trips on a slow crash. A service that keeps failing is retried every 3 seconds instead of being parked, so watch it with monitoring rather than relying on failed. StartLimit* belongs in [Unit] per systemd.unit(5). systemd 261 here still accepted the older StartLimitInterval= in [Service], but do not rely on it.
The same unit after that change, three seconds after starting:
activating (auto-restart) means it is waiting out RestartSec before the next try. It is still broken, but it is no longer parked.
The Script
Save as start-limit-check.sh. It prints the limit math for a unit, says whether a crash loop can trip it, and when the unit is parked, prints the reset command and the last lines the program itself logged, with systemd's own lines filtered out.
Prerequisites
bash 4 or later and systemd (systemctl show, journalctl). No root for user units. For system units, run it with sudo or as a user in the systemd-journal or adm group, or the journal lookup returns nothing.
How Does Each Check Work?
systemctl showreads the values systemd is using, including defaults that are not written in the unit file:Result,Restart,RestartUSec,StartLimitBurst,StartLimitIntervalUSecandNRestarts.to_msconverts systemd's time strings (100ms,10s,1min 30s) to milliseconds so the two settings can be compared.- The loop test multiplies the burst by
RestartSec. If that fits inside the interval, a program that dies at once will always trip the limit, and the script prints theRestartSecthat would not. - The journal filter drops lines from
systemd[PID]and keeps the rest, which are the lines the service's own processes wrote. Those are what to fix.
What Does the Script Print?
On the parked unit from the top of the page:
The cause is the last three lines. The port is taken, which Kill a Process on a Port and the Open Ports Explainer help track down.
What About a Watchdog That Resets It?
A cron watchdog that runs reset-failed and start every minute turns systemd's crash-loop protection off and replaces it with a slower crash loop. Auto-Restart a Linux Service covers the bounded version, which resets a few times and then alerts a human, alongside Restart= and health checks. If the service never starts at all, with status=203/EXEC, see Fix systemd status=203/EXEC.
Frequently Asked Questions
What does start request repeated too quickly mean?
systemd started the service, it exited, Restart= started it again, and that happened more than StartLimitBurst times (5 by default) inside StartLimitIntervalSec (10 seconds by default). systemd then gives up and marks the unit failed with Result: start-limit-hit. The message is a symptom: the real error is whatever made the program exit five times, which is in journalctl -u UNIT.
How do I reset start-limit-hit in systemd?
Run systemctl reset-failed UNIT, then systemctl start UNIT (add --user for a user unit, sudo for a system unit). Until reset-failed clears the counter, systemd refuses every start request for that unit, including ones you type by hand, with Job for UNIT failed because start of the service was attempted too often.
Where do StartLimitBurst and StartLimitIntervalSec go?
In the [Unit] section, which is where systemd.unit(5) documents them, for example StartLimitIntervalSec=60 and StartLimitBurst=5. Older guides put StartLimitInterval= in [Service]; systemd 261 on this machine still accepted that form, but [Unit] is the documented one. Run systemctl daemon-reload after the edit and check with systemctl show -p StartLimitBurst -p StartLimitIntervalUSec UNIT.
Should I set StartLimitBurst=0 or StartLimitIntervalSec=0?
Setting StartLimitIntervalSec=0 disables the limit, so a broken service restarts forever. Combined with the default RestartSec=100ms that is ten starts a second, each one logging an error. Prefer a RestartSec= long enough that the burst cannot fit in the interval: with the defaults, RestartSec=3s means five restarts take 15 seconds and never trip the 10-second window, while a genuinely tight loop still gets stopped.
Why does systemctl status not show the real error?
Its log section shows only the last few journal lines for the unit, and after a crash loop those are systemd's own Start request repeated too quickly and Failed with result lines. In the run on this page, none of the program's own error lines were in the status view. journalctl -u UNIT -n 50 goes back far enough, or start-limit-check.sh prints the program's last lines with systemd's filtered out.
Part of the bash snippets collection
Related Scripts
- Fix systemd status=203/EXEC — when the program never starts at all
- Auto-Restart a Linux Service — Restart=, bounded resets and alerting
- Restart Service If Stopped — a cron watchdog done carefully
- Kill a Process on a Port — the most common reason a service cannot start twice