Home / Alt manpages / systemd.unit(5)

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

Safely Override a systemd Service with a Drop-in Unit

You will change one setting on an existing systemd service without editing the package-owned unit file. The result is a small drop-in under /etc/systemd/system/, followed by a daemon reload and a check of the merged configuration. 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. The commands that inspect units and validate a file can be run as an ordinary user; creating the system drop-in, reloading systemd, and starting a service require 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 being 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 that the service needs network-online.target to be 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 is started. It does not, by itself, make the service fail if the wanted unit fails. After= only controls start and stop ordering; it does not start anything. Using both 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 operational decision: use Requires= instead of Wants= only after checking the failure behaviour you need.

Drop-in files with the .conf suffix are merged after the main unit. Multiple files are applied in alphanumeric order. A later file can therefore override an earlier value, which is useful but also 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 it does not make a missing path appear after boot. Create the path separately, with the ownership and permissions required by the service, 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 show the values you added. systemctl show prints machine-readable properties, but its display is not a complete substitute for systemctl cat. If the new file is absent, 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 that the service will work or that the dependency is healthy.

5. Apply the change deliberately

Reloading changes how systemd will handle 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

A restart can interrupt clients and may discard in-memory state. Treat it as service-disrupting. If you only need the unit to use the change on its next start, leave the service 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 that every application function is healthy. Read the service's own health check or recent journal entries as well.

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 may need it again. An empty drop-in directory is harmless, but you can remove it after confirming that no other local files are present.

Three errors account for most failed overrides. First, After= is mistaken for a dependency: it orders units but does not pull the other unit in. Second, a setting that accepts one value is accidentally repeated, with the last value winning or the directive's documented reset behaviour being missed. Third, a template unit is edited as though it were one instance. For a name such as [email protected], systemd can load [email protected] and substitute the instance with specifiers such as %i. Use the instance-specific drop-in directory only when you intend to affect that instance.

Done means

  • The local change is 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, and its status and journal were checked.
  • You know the exact file to remove if the change needs to be undone.