Skip to content
daniel@cosenza:~/blog
LinuxFix July 7, 2026 2 min read

Fixing 'start-limit-hit' Errors in systemd

A service refuses to start at all, and systemctl reports start-limit-hit — this is systemd's own crash-loop protection, and it requires clearing the rate limit as a distinct step after fixing the real cause.

systemctl start myservice reports Failed to start myservice.service: Unit myservice.service not found — no wait, more precisely: “start request repeated too quickly” or “start-limit-hit” means systemd has deliberately stopped trying to start a unit that’s failed too many times in a short window.

Step 1: check the unit’s actual failure reason first

systemctl status myservice
journalctl -u myservice -n 50

The rate limit is systemd protecting against a genuine crash loop — fixing why the service keeps failing is the real work; clearing the rate limit alone just lets it fail rapidly again.

Step 2: identify and fix the actual underlying problem

Common causes behind the repeated failures: a missing configuration file, an unavailable dependency (a database the service can’t reach yet), incorrect permissions, or a bug triggered on every startup — the journal output from Step 1 should point at one of these directly.

Step 3: check the unit’s own rate-limit configuration

[Unit]
StartLimitIntervalSec=60
StartLimitBurst=3

This unit fails permanently after 3 restart attempts within 60 seconds — worth knowing these values exist and are adjustable, though the fix is rarely “just allow more retries.”

Step 4: reset the failed state once the real cause is fixed

systemctl reset-failed myservice

This clears systemd’s internal failure counter for the unit — required after fixing the underlying issue, since systemd won’t attempt a fresh start cycle until this counter is cleared.

Step 5: start the service again

systemctl start myservice

Step 6: watch it through a few natural restart cycles if it’s meant to restart on its own

journalctl -u myservice -f

For a service configured with Restart=on-failure, confirm it now survives whatever transient condition (a slow-starting dependency) previously triggered the loop, rather than hitting the same limit again after the reset.

Step 7: add an explicit dependency if the real cause was a race at boot

[Unit]
After=postgresql.service
Requires=postgresql.service

A service crash-looping specifically at boot, because a dependency (a database, a network mount) isn’t ready yet, is fixed properly by declaring that dependency explicitly — not by increasing the restart burst limit to outlast the race.

Why reset-failed is easy to forget

Fixing the root cause and restarting the service manually often works once — but systemd’s own internal failure counter persists across that manual start, meaning the very next automatic restart attempt (from a boot, or a monitoring system triggering a restart) can immediately hit the same limit again if it was never cleared. Making reset-failed a standard part of the fix, not an optional afterthought, avoids the confusing “I fixed it and it broke again” experience.