Unstable or failing systemd services on Linux often come from missing dependency units or runtime settings that point to the wrong executable, user, or file path. A fast dependency and path review usually surfaces the real cause sooner than repeated restarts and reduces the risk of hitting start-limit lockouts.
systemd builds the final service definition from the unit file plus any drop-in overrides under /etc/systemd/system/<unit>.d/, then computes the dependency graph from directives such as Requires, Wants, and ordering rules like After and Before. The same merged configuration also controls runtime behavior—ExecStart command paths, optional EnvironmentFile entries, the User and Group the process runs as, and any working or state directories the service expects.
Some dependencies are implicit (for example mount units derived from path usage) and drop-ins can override earlier settings, so checking the effective configuration matters more than reading a single file. systemd does not execute ExecStart through a shell, so relative paths, shell built-ins, and interactive quoting assumptions can fail in a unit context. File and directory checks may require sudo privileges, and remote systems benefit from having console access available before applying changes that affect service startup.
Steps to check Linux service dependencies and runtime paths with systemctl:
- Display the effective unit file and any drop-in overrides.
$ systemctl --no-pager cat ssh.service # /usr/lib/systemd/system/ssh.service [Unit] Description=OpenBSD Secure Shell server Documentation=man:sshd(8) man:sshd_config(5) After=network.target auditd.service ConditionPathExists=!/etc/ssh/sshd_not_to_be_run [Service] EnvironmentFile=-/etc/default/ssh ExecStartPre=/usr/sbin/sshd -t ExecStart=/usr/sbin/sshd -D $SSHD_OPTS ExecReload=/usr/sbin/sshd -t ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartPreventExitStatus=255 Type=notify RuntimeDirectory=sshd RuntimeDirectoryMode=0755 [Install] WantedBy=multi-user.target Alias=sshd.service
Replace service-name.service with the actual unit name, including suffixes like .service, .socket, or .timer.
- Extract dependency directives from the effective unit file.
$ systemctl --no-pager cat ssh.service | grep -E '^(Requires|Wants|BindsTo|Requisite|PartOf|After|Before)=' After=network.target auditd.service
- List the resolved dependency tree for the unit.
$ systemctl --no-pager list-dependencies --after --all --plain --full ssh.service | head -n 12 ssh.service -.mount -.slice auditd.service ssh.socket system.slice sysinit.target dev-mqueue.mount systemd-journald.socket modprobe@dm_mod.service system-modprobe.slice modprobe@drm.service
Use --before to view reverse ordering, and --reverse to list units that pull the service in.
- Extract runtime path directives and service identity settings from the effective unit file.
$ systemctl --no-pager cat ssh.service | grep -E '^(ExecStart|ExecStartPre|ExecStartPost|WorkingDirectory|EnvironmentFile|User|Group|RuntimeDirectory|StateDirectory|CacheDirectory|LogsDirectory|ConfigurationDirectory|PIDFile)=' EnvironmentFile=-/etc/default/ssh ExecStartPre=/usr/sbin/sshd -t ExecStart=/usr/sbin/sshd -D $SSHD_OPTS RuntimeDirectory=sshd
A leading - in EnvironmentFile makes the file optional, while ExecStart must reference an absolute executable path because systemd does not invoke a shell.
- Verify that referenced executables and files exist and have expected permissions.
$ sudo ls -l /usr/sbin/sshd /etc/ssh/sshd_config /etc/default/ssh -rw-r--r-- 1 root root 133 Jul 21 15:58 /etc/default/ssh -rw-r--r-- 1 root root 3517 Aug 26 13:49 /etc/ssh/sshd_config -rwxr-xr-x 1 root root 921184 Aug 26 13:49 /usr/sbin/sshd
A missing ExecStart binary or an unreadable non-optional EnvironmentFile causes immediate start failure and may trigger systemd start-limit suppression (restarts blocked until the limit window resets).
- Check that referenced working or state directories exist and are owned appropriately for the configured service account.
$ sudo ls -ld /run/sshd /var/log drwxr-xr-x 2 root root 40 Jan 12 22:27 /run/sshd drwxrwxr-x 1 root syslog 4096 Jan 12 23:54 /var/log
Paths under /run/ are often created at service start and may not exist while stopped unless RuntimeDirectory (or similar) is configured.
- Confirm that prerequisite units from the dependency chain are active.
$ systemctl is-active network-online.target systemd-journald.socket inactive active
List globally failed units when a prerequisite is suspected:
$ systemctl --no-pager --failed
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
