systemctlでサービスが起動しない(Failed to start)

systemctl start でサービスを起動しようとしたら失敗した、あるいは起動した直後に落ちてしまう——という状況を切り分けていきます。

どんな症状か

systemctl start nginx のようにサービスを起動しようとした際、Job for nginx.service failed のようなメッセージが出て起動しない場合と、起動はするものの数秒後に systemctl status を見ると failed になっている(再起動を繰り返す)場合があります。どちらも同じ流れで原因を調べられます。

原因を切り分ける

ステップ1:まず概要を見る

$ systemctl status nginx.service
● nginx.service - A high performance web server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled)
     Active: failed (Result: exit-code) since ...
    Process: 1234 ExecStart=/usr/sbin/nginx (code=exited, status=1/FAILURE)

Active: の行で failed になっていることと、Result: の内容(exit-code か timeout かなど)を確認します。この時点ではまだ詳しい原因は分かりません。

ステップ2:詳しいログを見る

$ journalctl -xeu nginx.service
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: configuration file /etc/nginx/nginx.conf test failed

journalctl -xeu サービス名 で、そのサービスに関するログだけを新しい順に確認できます。上の例では「80番ポートがすでに使われている」ことが直接の原因だと分かります。

ステップ3:設定ファイルそのものを疑う

$ nginx -t
nginx: [emerg] unexpected "}" in /etc/nginx/nginx.conf:42
nginx: configuration file /etc/nginx/nginx.conf test failed

多くのデーモンには、設定ファイルの文法だけを事前チェックできるオプションがあります(nginx -t、sshd -t など)。設定を変更した直後に起動しなくなった場合は、まずこれを実行すると原因の行番号まで特定できます。

ステップ4:ポートの競合を疑う

$ ss -ltnp | grep :80
LISTEN 0  128  0.0.0.0:80  0.0.0.0:*  users:(("apache2",pid=987,fd=6))

Address already in use のようなエラーが出た場合は、ss -ltnp(または netstat -tlnp)で該当ポートをすでに使っているプロセスを特定します。上の例では apache2 が80番ポートを使用中であることが分かります。

解決方法

  • 設定ファイルの文法エラーが原因の場合: エラーで示された行を修正し、nginx -t のような検証コマンドで再確認してから起動し直します。
  • ポートが競合している場合: 不要な方のサービスを停止する(systemctl stop apache2)か、どちらかの待受ポート番号を変更します。
  • 設定ファイルを直したあと: systemctl daemon-reload を実行してから systemctl restart サービス名 します(unitファイル自体を変更した場合は特に必須です)。
  • 依存するサービスが先に起動していない場合: systemctl list-dependencies サービス名 で依存関係を確認します。
関連する章: 起動処理の流れは中級「システムのブートプロセスとGRUB」、systemdの詳しい仕組みは上級「システム起動のカスタマイズ(systemd詳細)」で扱っています。練習用ターミナルの運用保守フェーズの課題でも、似た調査の流れを試せます。