Systemd restart loop: 3 common causes and fixes
A unit keeps restarting? Usually it's a bad service file, a crash loop, or a dependency issue. Here's how to fix it fast.
Cause #1: The service file says Restart=always but the unit crashes on start
This is the big one. I see this all the time. Someone writes a service file with Restart=always, but the actual service crashes within seconds. Systemd then tries to restart it, it crashes again, and boom — you get a restart loop. The service file thinks it's being helpful, but it's not.
Check your service file — usually in /etc/systemd/system/ or /usr/lib/systemd/system/. Run this:
systemctl cat your-service.service
Look for a line like Restart=always or Restart=on-failure. If you see it, and the service keeps failing, you need to either fix the service itself or add a restart limit. The quick fix for a development box is to increase the limit, but for production you should fix the service.
To stop the loop temporarily, run:
systemctl reset-failed your-service.service
systemctl start your-service.service
That resets the start-limit-burst counter. But if the service still crashes, it'll loop again. The real fix is to check the logs with journalctl:
journalctl -u your-service.service --since "10 minutes ago" -n 50
Look for actual error messages — segfaults, missing config files, permission errors. That's where the root cause lives. I once spent an hour chasing a restart loop only to find a typo in a config file path. Don't be that guy.
Cause #2: StartLimitIntervalSec and StartLimitBurst are set too tight
Even if the service doesn't crash, sometimes systemd throttles restarts because of these two settings. The defaults are usually fine — 5 restarts within 10 seconds triggers the stop. But if you have a service that legitimately needs to restart a few times during startup (like a database with a slow init), you'll hit the limit.
Check your service file for these lines:
StartLimitIntervalSec=10s
StartLimitBurst=5
If you see them, or they're missing (which inherits system defaults), the fix is simple. Add this to the [Unit] section of your service file:
StartLimitIntervalSec=30s
StartLimitBurst=10
Or disable the limit entirely for testing (not for production!):
StartLimitIntervalSec=0
After you change the file, reload systemd:
systemctl daemon-reload
Then reset the failed state and start the service again:
systemctl reset-failed your-service.service
systemctl restart your-service.service
I've seen this fix work on CentOS 7 and Ubuntu 20.04 boxes where the service was a custom Java app that took 15 seconds to start. The default limit was killing it before it even had a chance. Simple fix, but you'd be surprised how many people miss it.
Cause #3: Dependency failures — the service depends on something that isn't ready
Sometimes the service itself is fine, but it depends on another unit that's not running or not ready. Systemd's ordering isn't always perfect, especially with network targets. If your service needs a database or a network mount, and that thing isn't up yet, your service will fail, systemd will retry, and you get a loop.
Look at the service file for lines like:
After=network.target
Requires=postgresql.service
If the dependency is flaky — like a network filesystem that mounts slow — you'll see errors in journalctl like:
Failed to connect to postgresql: Connection refused
Mount not ready, retrying...
The fix depends on what the dependency is. For a database, you can add a script that waits for it. But the simpler fix is to increase the timeout for the dependency. Add this to your service file's [Unit] section:
JobTimeoutSec=120
Or use a oneshot service to check the dependency before starting your main service. Create a helper like this:
[Unit]
Description=Wait for database
Requires=postgresql.service
After=postgresql.service
[Service]
Type=oneshot
ExecStart=/usr/bin/sleep 5
RemainAfterExit=yes
Then make your main service depend on that helper. This buys time. Ugly? Yeah. But it works, and I've used it on RHEL 8 boxes with slow SAN mounts.
One more thing — check if the dependency itself is in a restart loop. Run systemctl list-dependencies your-service.service and inspect each one. I've seen a case where the network service was flapping, which cascaded into everything else looping. Always check upstream first.
| Cause | Symptom | Fix |
|---|---|---|
| Service crashes immediately | journalctl shows segfaults or config errors | Fix the service code or config; add StartLimitBurst |
| Restart limits too tight | "start-limit-hit" in journalctl | Increase StartLimitIntervalSec or StartLimitBurst |
| Dependency not ready | "Connection refused" or mount errors | Add wait script or increase JobTimeoutSec |
Was this solution helpful?