When systemd Unit Files Don’t Pick Up Changes
You tweak a unit file, hit systemctl, and nothing happens.
That’s the classic “I changed the file, but systemd still runs the old version” problem.
The daemon is still holding the old config in memory. systemd keeps a cache of unit files; it only rereads them after a daemon‑reload. If you skip that step, the changes stay invisible until you reboot or reload manually.
Why the Cache Exists
At boot, systemd parses every unit file once and keeps the data in RAM.
Re‑parsing on every request would be slow and could introduce race conditions.
The cache also acts as a security boundary: a compromised unit file can’t silently alter its own behavior without an explicit reload.
The Right Sequence
- Edit the unit file (or drop a drop‑in in
/etc/systemd/system/.../override.conf). - Validate the syntax – a stray typo can silently fail.
systemd-analyze verify /etc/systemd/system/myapp.service - Reload the daemon so systemd sees the new file.
sudo systemctl daemon-reload - Apply the change to the running service.
- If the unit has a
Reload=directive, use:sudo systemctl reload myapp.service - Otherwise or if you want a full restart, use:
sudo systemctl restart myapp.service
- If the unit has a
reload-or-restart is handy when you’re not sure whether the unit supports reload.
It tries reload; if that fails, it falls back to restart.
sudo systemctl reload-or-restart myapp.service
Common Pitfalls
| Symptom | Likely Cause | Fix |
|---|---|---|
| Service still uses old config | Daemon not reloaded | systemctl daemon-reload |
systemctl reload fails with “Reload not supported” | No Reload= line | Add Reload=... or use restart |
| Unit file syntax error | Missed typo | systemd-analyze verify |
| Service restarts on every reload | Restart=always | Consider Restart=on-failure or remove the directive |
Security‑Friendly Practices
- Least‑privilege for unit files – always set
User=andGroup=explicitly. A rogue reload that restarts a privileged service can be mitigated by running the unit as a non‑root user. - Audit unit changes –
systemctl status --no-pagershows the active configuration. For critical services, keep a signed checksum of the unit file and verify it before reloading. - Avoid
restarton production services unless necessary – a full restart can expose a window where the service is unavailable. Preferreloadwhen the application supports it.
Real‑World Example
I added an Environment= variable to nginx.service to enable a custom log format.
sudo tee /etc/systemd/system/nginx.service.d/env.conf <<EOF
[Service]
Environment="NGINX_LOG_FORMAT=combined"
EOF
Validate, reload, and restart:
sudo systemctl daemon-reload
sudo systemctl reload-or-restart nginx.service
Check the effective environment:
systemctl show nginx.service --property=Environment
You’ll see the new variable applied without a full reboot.
When to Skip daemon-reload
- Transient units (created with
systemctl start myapp@.service) – they’re parsed on each start. - Drop‑in files added to an already loaded unit – systemd re‑reads drop‑ins on the next start, but a daemon‑reload guarantees consistency.
Quick Reference
# Edit unit
sudo nano /etc/systemd/system/myapp.service
# Verify syntax
systemd-analyze verify /etc/systemd/system/myapp.service
# Reload daemon
sudo systemctl daemon-reload
# Apply change
sudo systemctl reload-or-restart myapp.service
Follow this pattern and you’ll avoid the “nothing changed” headache.
The extra reload step is a tiny cost for predictable, auditable service behavior.
See also
- Resolving “Permission denied” When Moving Files Into a Sticky‑Bit Directory Using ACLs
- Web Application and API Protection (WAAP) platforms and Next-Generation WAFs (NGWAF)
- How to Use systemd‑resolved to Serve a Local Search Domain on My Home Network
- Pulling a Single File from a Borg Backup Without Unpacking the Whole Archive
- Stop systemd‑journald from filling your Raspberry Pi’s 8 GB SD card with logs – how to cap its size