やりたいこと

サーバーの再起動後やデプロイ後に、起動に失敗しているsystemdのユニットがないかをまとめて確認したい。

systemctl status [ユニット名]でユニットごとの詳細は確認できる。 ただし、どのユニットが失敗しているかわからない状態では、失敗したユニットだけを一覧表示する方法が必要になる。

systemctl –failed

systemctl --failedを実行すると、状態がfailedのユニットだけを一覧表示できる。

$ systemctl --failed
  UNIT            LOAD   ACTIVE SUB    DESCRIPTION
● myapp.service   loaded failed failed My sample application
● mybatch.service loaded failed failed My batch job

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.

2 loaded units listed.

ACTIVE列がfailedのユニットが表示される。 失敗したユニットがない場合は0 loaded units listed.と表示される。

$ systemctl --failed
  UNIT LOAD ACTIVE SUB DESCRIPTION

0 loaded units listed.

--failedは--state=failedの省略形である。 systemctl --helpにもShortcut for --state=failedと記載されている。 以下のコマンドはどれも同じ結果になる。

$ systemctl --failed
$ systemctl list-units --failed
$ systemctl list-units --state=failed

具体例

起動コマンドが成功しても失敗しているユニットを見つける

Type=simple(デフォルト)のサービスは、プロセスを起動した時点でsystemctl startが成功を返す。 起動直後にプロセスが異常終了した場合も、systemctl startの終了コードは0になる。

以下のユニットで確認する。

[Unit]
Description=My sample application

[Service]
ExecStart=/bin/sh -c 'echo "config not found" >&2; exit 1'

systemctl startの終了コードは0である。

$ sudo systemctl start myapp.service
$ echo $?
0

systemctl --failedを実行すると、myapp.serviceがfailedの状態で表示される。

$ systemctl --failed
  UNIT          LOAD   ACTIVE SUB    DESCRIPTION
● myapp.service loaded failed failed My sample application
...

失敗の原因はsystemctl statusで確認できる。

$ systemctl status myapp.service
× myapp.service - My sample application
     Loaded: loaded (/etc/systemd/system/myapp.service; static)
     Active: failed (Result: exit-code) since Sat 2026-11-14 06:03:40 UTC; 1s ago
   Duration: 915us
    Process: 133 ExecStart=/bin/sh -c echo "config not found" >&2; exit 1 (code=exited, status=1/FAILURE)
   Main PID: 133 (code=exited, status=1/FAILURE)
        CPU: 651us

Nov 14 06:03:40 c3c3ae659236 systemd[1]: Started myapp.service - My sample application.
Nov 14 06:03:40 c3c3ae659236 sh[133]: config not found
Nov 14 06:03:40 c3c3ae659236 systemd[1]: myapp.service: Main process exited, code=exited, status=1/FAILURE
Nov 14 06:03:40 c3c3ae659236 systemd[1]: myapp.service: Failed with result 'exit-code'.

参考: journalctlでsystemdのサービスのログを見る

ユニットの種類で絞り込む

--typeオプションと組み合わせると、ユニットの種類で絞り込める。 以下はサービスだけを表示する例。

$ systemctl --failed --type=service

タイマーだけを表示する場合は--type=timerを指定する。

スクリプトで扱いやすい形式で出力する

--plainで先頭の●を、--no-legendでヘッダーと凡例を省略できる。 失敗したユニット名をスクリプトで処理する場合に便利である。

$ systemctl --failed --plain --no-legend
myapp.service   loaded failed failed My sample application
mybatch.service loaded failed failed My batch job

ユニット名だけを取り出す例。

$ systemctl --failed --plain --no-legend | awk '{print $1}'
myapp.service
mybatch.service

失敗したユニットの有無にかかわらず、systemctl --failedの終了コードは常に0である。 スクリプトで失敗を判定したい場合は、後述のsystemctl is-failedやsystemctl is-system-runningを使う。

関連するコマンド

systemctl is-failed

systemctl is-failedはユニット名を指定して、そのユニットがfailedかどうかを判定する。 failedの場合は終了コード0、それ以外の場合は0以外を返す。

$ systemctl is-failed myapp.service
failed
$ echo $?
0
$ systemctl is-failed systemd-journald.service
active
$ echo $?
1

systemctl is-system-running

failedのユニットが1つでもあると、systemctl is-system-runningはdegradedを返す。 終了コードも0以外になる。

$ systemctl is-system-running
degraded
$ echo $?
1

起動処理が完了していて失敗したユニットがない場合はrunningを返し、終了コードは0になる。

$ systemctl is-system-running
running
$ echo $?
0

起動処理中のstartingや停止処理中のstoppingでも、終了コードは0以外になる。 失敗したユニットの有無だけを判定したい場合は、終了コードではなく出力がdegradedかどうかで判定する。

if [ "$(systemctl is-system-running)" = "degraded" ]; then
  systemctl --failed
fi

systemctl reset-failed

failedの状態はユニットの起動に再び成功するか、systemctl reset-failedを実行するまで残る。 原因を調査し終えたユニットを一覧から消すにはsystemctl reset-failedを使う。

ユニット名を指定すると、指定したユニットのfailed状態だけをリセットする。

$ sudo systemctl reset-failed mybatch.service
$ systemctl --failed
  UNIT          LOAD   ACTIVE SUB    DESCRIPTION
● myapp.service loaded failed failed My sample application
...

ユニット名を省略すると、すべてのユニットのfailed状態をリセットする。

$ sudo systemctl reset-failed
$ systemctl --failed
  UNIT LOAD ACTIVE SUB DESCRIPTION

0 loaded units listed.

systemctl reset-failedはユニットの状態だけをリセットする。 ユニットファイルは削除されない。

動作確認した環境

Ubuntu 24.04のDockerコンテナでsystemdを起動して動作を確認した。

$ systemctl --version
systemd 255 (255.4-1ubuntu8.18)

参考