Home / Alt manpages / systemd.unit(5)

  • systemd.unit(5)
  • File format
  • linux

Override a systemd Unit Safely with a Drop-in

A systemd.unit drop-in lets you change one setting on an existing service without touching the package-owned unit file. This guide walks through creating one under /etc/systemd/system/, reloading the daemon, and checking the merged configuration actually took. The examples use a dependency and a path assertion because they show the difference between ordering, requirement, and a precondition.

This guide describes systemd 255.4-1ubuntu8.17, installed on the machine used for these examples. Allow about 10 minutes. You need an existing service name and sudo access. Commands that only inspect units or validate a file can run as an ordinary user; creating the system drop-in, reloading systemd, and starting a service need elevated privileges.

1. Choose and inspect the unit

Replace example.service with the real service you intend to change. Start by confirming its exact name and seeing where its main file comes from.

systemctl status example.service --no-pager
systemctl cat example.service

systemctl cat shows the main unit and any drop-ins already loaded. A service may be supplied by a package under /usr/lib/systemd/system/, while local administrator changes belong under /etc/systemd/system/. Do not edit the vendor file: a package upgrade can replace it, and the change becomes harder to find or undo.

Checkpoint

Write down the service name and the setting you are changing. If the unit is not found, stop here and check for a spelling error with systemctl list-unit-files | rg 'example'.

2. Create a narrow drop-in

The drop-in directory must be named after the complete unit, including .service, followed by .d. This example adds a description and says the service needs network-online.target present before it starts.

sudo install -d /etc/systemd/system/example.service.d
sudoedit /etc/systemd/system/example.service.d/10-local.conf

Enter this file content:

[Unit]
Description=Example service with a local override
Wants=network-online.target
After=network-online.target
  • Wants= requests the other unit when this one starts, but does not by itself fail the service if the wanted unit fails.
  • After= only controls start and stop ordering; it does not start anything.
  • Using both together is the usual pattern when a service should request a unit and wait for it. If the service must not start without the other unit, that is a stronger decision: use Requires= instead of Wants=, only after checking the failure behaviour you actually need.

Drop-in files with the .conf suffix merge after the main unit, applied in alphanumeric order. A later file can override an earlier value, which is useful but an easy source of confusion. Keep local files clearly named and avoid copying a whole vendor unit into the drop-in.

3. Add a precondition when the service needs one

Dependencies are not the same as checks. If the service should only start when a directory exists, add an assertion to the same drop-in:

[Unit]
AssertPathExists=/srv/example

An assertion prevents activation when its condition is false. It does not create the directory and does not make a missing path appear after boot. Create the path separately, with the ownership and permissions the service needs, or remove this assertion if it was only an example.

Do not add a condition casually to a production service. A failed condition can look like a service that was ignored rather than one that crashed. Check the journal and unit status when diagnosing it:

systemctl status example.service --no-pager
journalctl -u example.service -b --no-pager

4. Reload and inspect the merged result

Writing a unit file does not make a running systemd manager reread it. Reload the manager, then ask systemd to display the effective unit.

sudo systemctl daemon-reload
systemctl cat example.service
systemctl show example.service -p Description -p Wants -p After -p AssertPathExists

The output should include the drop-in path and the values you added. systemctl show prints machine-readable properties, but it is not a full substitute for systemctl cat. If the new file is missing from the output, check the directory spelling, the .conf suffix, and the result of systemd-analyze verify.

systemd-analyze verify /etc/systemd/system/example.service.d/10-local.conf

A successful verification normally produces no output and returns exit status zero. It checks syntax and references; it does not prove the service will work or that the dependency is healthy.

5. Apply the change deliberately

Reloading changes how systemd handles the next operation. It does not automatically restart an already-running service. If the setting should apply now, restart it during an approved maintenance window:

sudo systemctl restart example.service
systemctl is-active example.service
systemctl status example.service --no-pager

Warning

A restart can interrupt clients and may discard in-memory state. Treat it as service-disrupting. If the unit only needs to pick up the change on its next start, leave it running and verify after its planned restart instead.

For an inactive unit, use sudo systemctl start example.service and inspect the status. A result of active is useful evidence, but it does not prove every application function is healthy. Read the service's own health check or recent journal entries too.

Undo and common traps

The drop-in is the local state you added. To undo it, remove that one file, reload systemd, and restart the service only if you restarted it for the change:

sudo rm /etc/systemd/system/example.service.d/10-local.conf
sudo systemctl daemon-reload
systemctl cat example.service

The removal is deliberate and irreversible unless you saved the file content, so copy it somewhere safe first if you might need it again. An empty drop-in directory is harmless, but you can remove it once you confirm no other local files are present.

  • After= mistaken for a dependency. It orders units but does not pull the other unit in.
  • A single-value setting repeated by accident. The last value wins, or the directive's documented reset behaviour gets missed.
  • A template unit edited as though it were one instance. For a name such as [email protected], systemd loads [email protected] and substitutes the instance with specifiers such as %i. Use the instance-specific drop-in directory only when you mean to affect that instance.

Done means

  • The local change sits in /etc/systemd/system/example.service.d/*.conf, not a package-owned file.
  • systemd-analyze verify returned success.
  • systemctl daemon-reload completed, and systemctl cat shows the drop-in.
  • The service was restarted only with an approved window, its status and journal checked afterwards.
  • You know the exact file to remove if the change needs undoing.