できない.dev

WSL で systemctl が使えない(System has not been booted with systemd)

WSL の既定の init は systemd ではないため systemctl が動かない。/etc/wsl.conf に [boot] systemd=true を書いて wsl --shutdown で再起動すれば有効になる。

公開: 更新:

実行例あり(2026-09-27 に実環境で検証)

要約

WSL の中で systemctl を叩くとエラーになり、Docker や PostgreSQL をサービスとして起動できない。

sudo systemctl status ssh
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

2 行目は systemd のバージョンで文言が違い、Ubuntu 26.04(systemd 259)では Failed to connect to system scope bus via local transport: Host is down と表示される(Ubuntu 22.04・24.04 の systemd 249・255 は上と同じ)。

原因は WSL が既定では systemd を PID 1 として起動していないことである。
WSL は独自の init プロセスで Linux を立ち上げるため、systemd を前提にしたコマンドがそのままでは通らない。

公式ドキュメント(新しいタブで開く)のとおり、/etc/wsl.conf に 2 行足して WSL を再起動すれば systemd が PID 1 になる。
設定はディストリビューションごとに独立している。

実行例

[boot] に systemd=true がある WSL2 の Ubuntu で systemd=false に書き換え、wsl --terminate Ubuntu で再起動すると PID 1 は init(Ubuntu) になり、systemctl status ssh は System has not been booted with systemd as init system (PID 1). Can't operate. で止まった。systemd=true に戻して同じように再起動すると PID 1 は systemd に戻り、systemctl list-units で実行中のサービスが 16 件並んでいる。

$ cat /etc/wsl.conf
[boot]
systemd=true
$ ps -p 1 -o comm=
systemd
$ systemctl is-system-running
running
$ printf '[boot]\nsystemd=false\n' > /etc/wsl.conf
$ wsl --terminate Ubuntu
この操作を正しく終了しました。
$ ps -p 1 -o comm=
init(Ubuntu)
$ systemctl status ssh
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to system scope bus via local transport: Host is down
$ printf '[boot]\nsystemd=true\n' > /etc/wsl.conf
$ wsl --terminate Ubuntu
この操作を正しく終了しました。
$ ps -p 1 -o comm=
systemd
$ systemctl list-units --type=service --state=running
  UNIT                        LOAD   ACTIVE SUB     DESCRIPTION
  chrony.service              loaded active running chrony, an NTP client/server
  console-getty.service       loaded active running Console Getty
  cron.service                loaded active running Regular background program processing daemon
  dbus.service                loaded active running D-Bus System Message Bus
  getty@tty1.service          loaded active running Getty on tty1
  networkd-dispatcher.service loaded active running Dispatcher daemon for systemd-networkd
  rsyslog.service             loaded active running System Logging Service
  snapd.service               loaded active running Snap Daemon
  systemd-journald.service    loaded active running Journal Service
  systemd-logind.service      loaded active running User Login Management
  systemd-resolved.service    loaded active running Network Name Resolution
  systemd-timedated.service   loaded active running Time & Date Service
  systemd-udevd.service       loaded active running Rule-based Manager for Device Events and Files
  unattended-upgrades.service loaded active running Unattended Upgrades Shutdown
  user@0.service              loaded active running User Manager for UID 0
  wsl-pro.service             loaded active running Bridge to Ubuntu Pro agent on Windows
 
Legend: LOAD   → Reflects whether the unit definition was properly loaded.
        ACTIVE → The high-level unit activation state, i.e. generalization of SUB.
        SUB    → The low-level unit activation state, values depend on unit type.
 
16 loaded units listed.

— 2026-09-27 時点の出力

検証環境

検証日
実行環境
local host (Windows 11 Home, Docker 29.8.0)
バージョン
  • Node.js 22.14.0
  • npm 10.9.2
  • Git 2.48.1.windows.1
  • Docker 29.8.0

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

よくある原因

  1. wsl.conf に設定が無い: systemd はディストリビューションごとのオプトインで、既定では無効である。
    Microsoft Store から入れた Ubuntu では最初から有効になっている場合もあるが、既存の環境を使い続けているなら書かれていないことが多い。
  2. wsl --shutdown をしていない: wsl.conf は起動時にしか読まれない。
    ウィンドウを閉じただけではディストリビューションのプロセスが残るため、設定を書いても反映されない。
  3. WSL 本体が古い: systemd サポートは WSL 0.67.6 以降で入った。
    Windows の「オプション機能」として入れた古い WSL のままだと、wsl.conf に書いても無視される。
  4. WSL 1 で動いている: WSL 1 は Linux カーネルを持たず、システムコールを変換して動く方式なので systemd を有効にできない。wsl -l -v の VERSION 列が 1 なら、まず WSL 2 へ変換する。
  5. セクション名が違う: systemd=true は [boot] セクションに置く必要がある。[wsl2] や [user] の下に書いても効かない。[boot] 自体を書き忘れているケースも多い。

解決策

1. /etc/wsl.conf を書く

WSL の中で編集する。
ファイルが無ければ新規に作る。

sudo tee /etc/wsl.conf > /dev/null <<'EOF'
[boot]
systemd=true
EOF

tee はファイルを丸ごと上書きする。
既に /etc/wsl.conf がある場合は、[network] など他のセクションの設定を消さないよう、エディタで開いて [boot] セクションに systemd=true の行を足す([boot] が無ければセクションごと足す)。
同じセクションを 2 つ書かないよう注意する。

2. wsl --shutdown で完全に止める

ここが抜けると設定が反映されない。Windows 側の PowerShell またはコマンドプロンプトで実行する。

wsl --shutdown

すべてのディストリビューションと WSL の仮想マシンが停止する。
そのあと改めて端末を開くと、systemd が PID 1 として起動する。
確認は次のコマンドで行う。

ps -p 1 -o comm=
systemctl list-units --type=service --state=running

1 行目が systemd を返せば成功である。

3. WSL 本体を更新する

wsl.conf を書いても変わらないときは、まず WSL のバージョンを見る。

wsl --version

このコマンド自体が「認識されていない」と言われる場合、systemd をサポートしないビルドである。
ストア版へ更新する。

wsl --update

更新後に wsl --shutdown をもう一度実行する。

4. WSL 1 なら WSL 2 に変換する

wsl -l -v
wsl --set-version Ubuntu 2

変換はディスクイメージの作り直しになるため、サイズによっては数分から十数分かかる。
変換前にバックアップを取っておくと安全である。
なお、Windows のファイルシステム上のファイルへ大量にアクセスする用途では WSL 1 のほうが速いという性質があるので、変換の前に用途を確認しておくとよい。

この記事は役立ちましたか?