systemd: Start request repeated too quickly — StartLimitBurst in [Service] still works, StartLimitIntervalSec does not
lab-flap.service: Start request repeated too quickly.
lab-flap.service: Failed with result 'exit-code'.What you see
A service restarts a few times and then stops for good. systemctl status reports:
lab-flap.service: Start request repeated too quickly.
lab-flap.service: Failed with result 'exit-code'.
Active: failed (Result: exit-code)
The unit has a StartLimit setting, the value in the file is not the value the system used, and every tutorial you find says the opposite of what this page measured.
Why it happens
StartLimitBurst and StartLimitInterval define a sliding window: if the unit is started Burst times within Interval, systemd stops trying. The defaults are 5 starts in 10 seconds, and they apply whether or not you write anything.
What changed in systemd 230 (2016) is narrower than the usual summary. The keys were not moved from [Service] to [Unit] wholesale. Instead:
[Unit]started to be read for these keys (before 230 it was not read at all)StartLimitIntervalwas renamed toStartLimitIntervalSec[Service]kept acceptingStartLimitBurstand the old nameStartLimitInterval- only the new name
StartLimitIntervalSecis refused outside[Unit]
So the modern spelling in [Service] is the one combination that breaks — and it breaks quietly enough that nobody notices.
What each section actually accepts
Measured on both systems, same unit, one variable changed per run:
| Written where | Key name | CentOS 7 · systemd 219 | Debian 13 · systemd 257 |
|---|---|---|---|
[Unit] | StartLimitBurst | ignored (stays 5) | applied |
[Unit] | StartLimitInterval | ignored (stays 10s) | applied |
[Unit] | StartLimitIntervalSec | key does not exist | applied |
[Service] | StartLimitBurst | applied | applied |
[Service] | StartLimitInterval (old name) | applied | applied, no warning |
[Service] | StartLimitIntervalSec (new name) | key does not exist | refused, falls back to 10s |
| drop-in | [Unit] StartLimitBurst | ignored | applied |
The nine runs on systemd 257
Debian 13, systemd 257.13-1~deb13u1, kernel 6.12.111+deb13-amd64. Unit: ExecStart=/bin/false, Restart=always, RestartSec=1. Effective values come from systemctl show.
| Run | Written | Effective burst | Effective window | Restarts | End state | analyze verify |
|---|---|---|---|---|---|---|
| A | nothing | 5 | 10s | 5 | failed | clean |
| B | [Service] burst=3, IntervalSec=60 | 3 | 10s | 3 | failed | Unknown key line 11 |
| C | [Unit] burst=3, IntervalSec=60 | 3 | 1min | 3 | failed | clean |
| D | [Unit] 3/60s + drop-in burst=8 | 8 | 1min | 8 | failed | clean |
| E | [Unit] IntervalSec=0 | 5 | 0 | 14 in 18s | still restarting | clean |
| F | [Service] IntervalSec=0 | 5 | 10s | 5 | failed | Unknown key line 10 |
| G | [Service] burst=3, Interval=60 (old name) | 3 | 1min | 3 | failed | clean |
| H | [Unit] IntervalSec=60, [Service] burst=3 | 3 | 1min | 3 | failed | clean |
| I | nothing, RestartSec=6 | 5 | 10s | 7 | still restarting | clean |
Run B is the one that matters. The burst came from your file, the window did not:
/etc/systemd/system/lab-flap.service:11: Unknown key 'StartLimitIntervalSec' in section [Service], ignoring.
Run G is the other one that matters. Change nothing but the key name and the window is accepted with no warning at all.
The same nine runs on systemd 219
CentOS 7, systemd 219, kernel 3.10.0-1127.el7.x86_64. Identical unit, identical sequence.
| Run | Written | Effective burst | Effective window | Behaviour |
|---|---|---|---|---|
| A | nothing | 5 | 10s | stopped after 5 |
| B | [Service] burst=3, Interval=60 | 3 | 60s | stopped after 3 |
| C | [Unit] burst=3, Interval=60 | 5 | 10s | [Unit] not read at all |
| D | [Unit] 3/60s + drop-in burst=8 | 5 | 10s | drop-in ignored |
| E | [Unit] Interval=0 | 5 | 10s | still limited |
| F | [Service] Interval=0 | 5 | 0 | 15 restarts in 18s, unlimited |
| G | [Service] burst=3, Interval=60 | 3 | 60s | same as B |
| H | [Unit] Interval=60, [Service] burst=3 | 3 | 10s | only the [Service] half applied |
| I | nothing, RestartSec=6 | 5 | 10s | 8 attempts, never limited |
On 219 the rule is simple: [Unit] is not read, [Service] is. Anything you put in [Unit] — including a drop-in — is silently discarded.
The version differences that break scripts
| systemd 219 | systemd 257 | |
|---|---|---|
| Property name | StartLimitInterval (microseconds, integer) | StartLimitIntervalUSec (10s, 1min) |
| Restart counter | no NRestarts property | NRestarts |
Result value | start-limit | exit-code |
| Log wording | start request repeated too quickly for lab-flap.service | lab-flap.service: Start request repeated too quickly. |
journalctl -o short-unix | unsupported | supported |
Monitoring scripts that query -p StartLimitIntervalUSec get an empty value on RHEL 7 and CentOS 7. Scripts that grep for start-limit-hit find nothing on either version.
Fix
1. Portable unit — [Service] with the old key names. Verified on both 219 and 257:
[Service]
StartLimitBurst=3
StartLimitInterval=60
2. Modern-only unit — [Unit] with the current key names:
[Unit]
StartLimitIntervalSec=60
StartLimitBurst=3
3. Drop-ins. Write the same section the system actually reads. On a fleet that still has 7-series hosts, that means [Service]:
# /etc/systemd/system/myapp.service.d/limits.conf
[Service]
StartLimitBurst=10
StartLimitInterval=120
4. To disable rate limiting entirely, StartLimitIntervalSec=0 must be in [Unit] on systemd 230 and later, and StartLimitInterval=0 must be in [Service] on 219. There is no single spelling that disables it on both.
5. Before blaming the limit, check RestartSec. With RestartSec=1 the measured gap between starts is 1.24–1.26 seconds, not 1.00 — systemd spends about 250 ms per cycle. With RestartSec=6 the gap is 6.25 seconds. Five starts need four gaps, so the default 5-in-10s limit stops triggering at roughly RestartSec=2.25 and above: the window fills with at most two starts and the unit restarts forever (run I: 7 restarts, still activating).
Verify
systemctl show myapp.service -p StartLimitBurst -p StartLimitIntervalUSec
systemd-analyze verify /etc/systemd/system/myapp.service
The first command prints what systemd will actually use, not what your file says. The second prints the Unknown key warning if the name is wrong for that section. Both are cheap; the second one is the only place the mistake shows up before it bites.
What failed
Four things in this lab did not match what I expected. The first two are the reason this page exists.
| Expectation | What actually happened | Why |
|---|---|---|
[Service] is not read for StartLimit* since systemd 230 | StartLimitBurst in [Service] applied on 257 (3 restarts) | the keys were added to [Unit], not removed from [Service]; only the renamed StartLimitIntervalSec is refused there |
hitting the limit sets Result=start-limit-hit | 257 reports Result=exit-code; 219 reports Result=start-limit | neither version uses that string; grepping for it is a dead end |
| a wrong section produces no warning at all | Unknown key 'StartLimitIntervalSec' in section [Service], ignoring. appears in the journal and in systemd-analyze verify | the warning exists, but only at daemon-reload time — nobody watches for it |
centring an 18-second observation on RestartSec=1 is enough to see the limit | run I never hit it | the limit is a sliding window, and RestartSec=6 moves every start out of the previous window |
One methodology note, because it cost a full re-run: the first version of the harness deleted the drop-in directory after creating it, so run D reported the [Unit] value and looked like a working result. Re-running with the harness fixed produced 8 restarts instead of 3. A plausible number was the symptom, not the proof.