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:

  1. 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.

  2. 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
  3. 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.

  4. 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.

  5. 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).

  6. 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.

  7. 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