Troubleshooting

systemctl: command not found? You are not on systemd

systemd is not PID 1. In Docker run the program directly, on Alpine use rc-service, on WSL set systemd=true in /etc/wsl.conf, on macOS use brew services.

Published · Updated ~7 min read
On this page

Short answer: systemctl: command not found almost always means the machine is not running systemd: a Docker container, Alpine Linux with OpenRC, WSL without systemd switched on, an older SysVinit system, or macOS. The fix is not to install systemctl; it is to use the service manager the machine actually has. One line tells you which:

Linux
cat /proc/1/comm

systemd means systemctl should work (see the PATH case). Anything else: run the program directly in a container, use rc-service on Alpine, service on SysVinit, systemd=true in /etc/wsl.conf on WSL, and brew services or launchctl on a Mac.

Which error do you see?

Two families of messages exist. Either the shell finds no systemctl at all, or systemctl is installed and finds no systemd to talk to. The second pair below is real output of Debian 12’s systemctl (systemd 252) on a system where systemd is not running; the newer wording is from systemd 257 in Debian 13 and is unchanged in 259, which Ubuntu 26.04 ships.

MessageWhere you see itGo to
bash: systemctl: command not foundno systemd installed: container, Alpine with bash, SysVinitWhich init
/bin/sh: 1: systemctl: not founddash (Debian, Ubuntu) in a Dockerfile RUN line or a cron job; a #!/bin/sh script prints its own name and line instead, as in ./setup.sh: 3: systemctl: not foundDocker
/bin/sh: systemctl: not foundthe same on Alpine (BusyBox); a login shell prints -sh:Alpine
zsh: command not found: systemctlmacOS, which has launchd, not systemdmacOS
System has not been booted with systemd as init system (PID 1). Can't operate.systemctl installed, PID 1 is not systemd: container or WSLDocker
Failed to connect to bus: Host is downsecond line of the above, systemd 256 and older (Debian 12, Ubuntu 24.04)WSL
Failed to connect to system scope bus via local transport: Host is downthe same second line from systemd 257 on (Debian 13; Ubuntu 26.04 has 259)WSL
You are attempting to run an openrc service on arc-service in an Alpine container OpenRC did not bootAlpine
Failed to connect to bus: No medium foundsystemctl --user after su or sudo -u, systemd 250 to 256 (Debian 12, Ubuntu 24.04)User services
Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not definedthe same on systemd 249 (Ubuntu 22.04)User services
Failed to connect to user scope bus via local transport: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not definedthe same from systemd 257 on (Debian 13, Ubuntu 26.04)User services

First, find out what init you have

Linux
cat /proc/1/comm      # prints: systemd, init, bash, node, ...
ps -p 1 -o comm=

ps is often missing in containers; /proc/1/comm always works. Read the answer like this:

  • systemd: systemd is running, and systemctl should exist. Go to the PATH case.
  • init: one of three systems. Alpine (BusyBox init, which starts OpenRC), SysVinit (Devuan, MX Linux, Debian before version 8), or an older WSL running its own init. The next block tells them apart.
  • init(Ubuntu), init(Debian) or another distribution name in brackets: current WSL, whose own init names itself that way. Go to WSL.
  • Anything else, such as bash, sh, node, nginx, tini or docker-init: you are in a container whose first process is the application. Go to Docker.
Linux
grep -i microsoft /proc/version    # any output: WSL
command -v rc-service               # a path: OpenRC (Alpine)
grep PRETTY_NAME /etc/os-release

In a Docker container

A container runs one process tree, and its PID 1 is your application or a tiny init such as tini, not systemd. The official debian, ubuntu and alpine images do not even include systemctl. If a package pulled systemd in, it is there but refuses:

Example output (Debian 12)
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

Do not try to make systemctl work. Start the program in the foreground, which is what the official images do:

Dockerfile
CMD ["nginx", "-g", "daemon off;"]

Inside a running container, call the program itself: nginx -s reload instead of systemctl reload nginx. On Debian and Ubuntu images, service SERVICE start still works for packages that ship a script in /etc/init.d/: the service wrapper hands over to systemctl only when /run/systemd/system exists and otherwise runs the script. Without a script it answers SERVICE: unrecognized service.

On WSL

WSL starts each distribution with its own init unless told otherwise. PID 1 is then WSL’s init, which current versions name after the distribution: cat /proc/1/comm prints init(Ubuntu), older ones plain init. systemctl is then either missing or prints the two lines above. Ubuntu installed with wsl --install has systemd on by default; for other distributions, such as Debian, switch it on per distribution. It needs WSL 2 and WSL version 0.67.6 or newer (wsl --version shows it; wsl --update updates it). On Debian, Ubuntu and Kali, Microsoft’s guide also asks for the systemd and systemd-sysv packages; install them before the switch:

WSL · Debian · Ubuntu · Kali
sudo apt-get update && sudo apt-get install -y systemd systemd-sysv

Then add this to /etc/wsl.conf inside the distribution (with sudo nano /etc/wsl.conf):

/etc/wsl.conf
[boot]
systemd=true

Restart WSL from Windows:

PowerShell
wsl.exe --shutdown

Open the distribution again and cat /proc/1/comm prints systemd. A distribution still on WSL 1 has no systemd support; convert it with wsl --set-version DISTRO 2.

Alpine (OpenRC)

A full Alpine install boots BusyBox init, which starts OpenRC. Its tools are rc-service, rc-update and rc-status:

Alpine · OpenRC
rc-service SERVICE start
rc-service SERVICE status
rc-update add SERVICE default

The last line is the equivalent of systemctl enable. In an Alpine container, OpenRC is usually not installed at all, and where it is, it did not boot the system: rc-service then prints a warning that begins You are attempting to run an openrc service on a and continues system which openrc did not boot. Run the program directly, as in Docker.

SysVinit

Devuan and MX Linux use SysVinit by default, and so did Debian before version 8. Services are scripts in /etc/init.d/, run through service:

Devuan · MX Linux · SysVinit
service SERVICE start
service SERVICE status
update-rc.d SERVICE defaults

update-rc.d SERVICE defaults enables a service at boot on Debian-style systems; update-rc.d SERVICE disable turns that off again.

systemctl commands and their equivalents

TasksystemdOpenRC (Alpine)SysVinit (Debian-style)macOS (Homebrew)
Startsystemctl start SERVICErc-service SERVICE startservice SERVICE startbrew services start FORMULA
Stopsystemctl stop SERVICErc-service SERVICE stopservice SERVICE stopbrew services stop FORMULA
Restartsystemctl restart SERVICErc-service SERVICE restartservice SERVICE restartbrew services restart FORMULA
Statussystemctl status SERVICErc-service SERVICE statusservice SERVICE statusbrew services info FORMULA
Start at bootsystemctl enable SERVICErc-update add SERVICE defaultupdate-rc.d SERVICE defaultsstart registers it
Stop starting at bootsystemctl disable SERVICErc-update del SERVICE defaultupdate-rc.d SERVICE disablestop unregisters it
List servicessystemctl list-units --type=servicerc-statusservice --status-allbrew services list

macOS: launchd instead of systemd

macOS has never had systemd; its service manager is launchd, driven by launchctl. For anything installed with Homebrew, brew services is the practical front end: it writes the launchd file for you. Without sudo it manages ~/Library/LaunchAgents, started at login; with sudo, /Library/LaunchDaemons, started at boot. launchctl list shows what launchd is running for your user.

If you do have systemd but the command is missing

systemctl lives in /usr/bin (also reachable as /bin/systemctl where /bin links to /usr/bin), which every default PATH includes, and sudo’s secure_path does too. So with systemd as PID 1, “not found” means PATH was overwritten, usually by a startup file that sets PATH without $PATH:

Linux
ls -l /usr/bin/systemctl
/usr/bin/systemctl status
echo "$PATH"

Restore PATH with export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH" and fix the line in ~/.bashrc or ~/.profile.

systemctl --user: Failed to connect to bus

systemctl --user talks to the user’s own service manager, and it finds that through the session a real login creates. After su or sudo -u that session is missing. systemd 250 to 256, as in Debian 12 and Ubuntu 24.04, then says only Failed to connect to bus: No medium found. Ubuntu 22.04 (systemd 249) prints Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=<user>@.host --user to connect to bus of other user), and systemd 257 and later print Failed to connect to user scope bus via local transport: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=<user>@.host --user to connect to bus of other user). Log in as that user over SSH, or address the user manager from root:

Linux (as root)
systemctl --user --machine=USERNAME@.host status

The user manager runs only while the user is logged in. For user services that must run without a login, enable lingering once: loginctl enable-linger USERNAME.

Verify it worked

Linux
systemctl is-system-running

running means systemd is in charge and healthy; degraded means it is in charge but a unit failed (systemctl --failed lists them). offline means systemctl is installed but systemd is not PID 1, which is what you get in a container or in WSL before the change above.

A full KVM VPS runs a normal systemd userland, so service management works exactly as the documentation expects. This is also why bots belong on a full VM: a Discord or Telegram bot under systemd restarts itself after a crash and at boot. Our Standard KVM line ships stock systemd images of Debian, Ubuntu, Rocky and more.

Writing a unit for your own program next? See how to create a systemd service.

Another tool missing, or a directory to add to PATH for good in bash, zsh and fish? See command not found: the three causes and the fix for every tool.

Frequently asked

What does 'System has not been booted with systemd as init system (PID 1)' mean?

systemctl is installed but systemd is not running as PID 1, typically in a Docker container or in WSL without systemd. In a container, start the program directly or use 'service NAME start' where the package ships an init script; on WSL, enable systemd in /etc/wsl.conf.

How do I get systemctl working in WSL?

Add '[boot]' and 'systemd=true' to /etc/wsl.conf inside the distribution, run 'wsl.exe --shutdown' from PowerShell and open it again. It needs WSL 2 and WSL 0.67.6 or newer, and on Debian the systemd and systemd-sysv packages; Ubuntu installed with 'wsl --install' already has it on.

What replaces systemctl on Alpine or macOS?

Alpine uses OpenRC: 'rc-service NAME start' and 'rc-update add NAME default' to start at boot. macOS uses launchd; for software from Homebrew, 'brew services start NAME' starts it and registers it to start at login.

Related articles

All troubleshooting