How systemctl mask Disables Services in Linux
In Linux systems powered by systemd, the systemctl mask
command renders a service completely unstartable—both automatically and
manually—by linking its configuration file to /dev/null.
While standard service management commands allow services to be
triggered by dependencies or explicit start calls, masking acts as an
absolute administrative lock. This article breaks down how systemd
handles the mask operation under the hood, how directory
precedence enforces this behavior, and how it differs from simply
disabling a service.
The Underlying
Mechanism: The /dev/null Symlink
When you execute systemctl mask <service_name>,
systemd does not delete the original service unit file. Instead, it
creates a symbolic link in the primary administrative unit directory
pointing directly to /dev/null:
/etc/systemd/system/<service_name>.service -> /dev/nullBecause /dev/null is a special file that discards all
data written to it and yields no output when read, systemd recognizes
this specific symlink target as a formal instruction that the unit is
completely blocked.
How systemd Evaluates Unit Precedence
To understand why the /dev/null symlink works, it is
essential to understand systemd's hierarchy of configuration
directories. When loading units, systemd searches through directories in
a strict order of priority:
- /etc/systemd/system/: System administrator overrides and custom units (Highest priority).
- /run/systemd/system/: Runtime units created dynamically while the system is running.
- /usr/lib/systemd/system/ or /lib/systemd/system/: Default unit files provided by the OS distribution or package maintainers (Lowest priority).
Under normal circumstances, an installed package places its
.service file inside /usr/lib/systemd/system/.
When systemctl mask is run, systemd places the dummy
/dev/null symlink in /etc/systemd/system/.
Because /etc/systemd/system/ takes precedence over
/usr/lib/systemd/system/, systemd loads the administrative
symlink and ignores the real unit file provided by the package.
systemctl mask
vs. systemctl disable
The key distinction between disabling and masking lies in how systemd treats activation triggers:
- Disabling a service
(
systemctl disable): systemd removes the symlinks from.wantsor.requiresdirectories located inside/etc/systemd/system/. This stops the service from launching automatically during the boot process. However, the unit file itself remains accessible. If another running service requires it, if a socket activates it, or if a user runssystemctl start <service_name>, the service will still launch. - Masking a service (
systemctl mask): Because the unit file itself is replaced by a link to/dev/null, systemd cannot parse any directives to run the service. Attempting to start the service manually produces an explicit error:Failed to start <service_name>.service: Unit <service_name>.service is masked.Masked units cannot be started by scripts, sockets, hardware events, or boot targets.
Runtime Masking
Linux administrators can also apply temporary masks using the
--runtime flag:
systemctl mask --runtime <service_name>When this flag is passed, systemd creates the /dev/null
symlink in /run/systemd/system/ rather than
/etc/systemd/system/. Because the /run/
directory resides in temporary memory (tmpfs), the mask remains active
only for the duration of the current session and disappears
automatically upon the next system reboot.
Reversing the Mask
To restore a masked service to its original state, the administrator runs:
systemctl unmask <service_name>This command deletes the /dev/null symlink from
/etc/systemd/system/ (or
/run/systemd/system/). With the override removed, systemd
falls back to the default unit configuration located in
/usr/lib/systemd/system/, returning the service to a
normal, operational state.