2026年10月1日
2026年10月1日
Nginxの設定文法チェックコマンド:nginx -t・-Tの使い方とエラーメッセージの読み方
Nginx の設定を変更したら、反映する前に sudo nginx -t を実行し、「syntax is ok」と「test is successful」の2行が出ることを確かめてから reload するのが基本です。この記事では、-t と -T を中心とした文法チェックコマンドの使い分け、よく出るエラーメッセージの読み方と直し方、チェックを通っても起動や反映で失敗するケース、そしてチェックを手順に組み込んで事故を防ぐ方法を説明します。
基本のコマンド
sudo nginx -t
成功すると次のように表示されます。
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
1行目は書式(括弧の対応、セミコロン、ディレクティブ名)に問題がないこと、2行目は証明書ファイルの読み込みやログファイルを開く処理など、実際に設定を組み立てる段階まで成功したことを示します。つまり -t は単なる文法の検査ではなく、「この設定で起動できるか」をかなりの範囲まで試してくれるコマンドです。
sudo を付けるのは、秘密鍵やログファイルが root でしか読み書きできないためです。一般ユーザーで実行すると「Permission denied」で失敗し、設定に問題がないのにエラーに見えることがあります。
オプションの使い分け
| コマンド | 用途 |
|---|---|
nginx -t |
設定をチェックして結果だけを表示する |
nginx -T |
チェックに加え、include で読み込まれた全ファイルの内容を連結して表示する |
nginx -t -q |
成功時は何も表示せず、エラーのときだけ出力する。スクリプト向け |
nginx -t -c /path/to/nginx.conf |
既定とは別の設定ファイルをチェックする |
nginx -V |
バージョンとビルド時のオプション(組み込みモジュール、設定ファイルの場所)を表示する |
-T は「どのファイルが実際に読み込まれているか」を知るのに役立ちます。設定を書いたのに効かない場合、sudo nginx -T | grep -n "server_name" のように検索すると、そのファイルが include されているか、同じ server_name が別の場所にもないかをすぐ確認できます。ただし出力には設定の全内容が含まれるため、パスワードファイルの場所や内部の IP アドレスなどを含む場合があります。サポートに送るときや公開の場に貼るときは、必要な部分だけを抜き出してください。
-c は、新しい設定一式を別ディレクトリで用意して、本番の設定に置き換える前に検査したいときに使えます。設定内の相対パスは Nginx のプレフィックス(-p で変更可能)を基準に解決される点に注意が必要です。
エラーメッセージの読み方
エラーは「何が問題か」と「どのファイルの何行目か」の組み合わせで表示されます。
nginx: [emerg] unknown directive "sever_name" in /etc/nginx/sites-enabled/example.com:3
nginx: configuration file /etc/nginx/nginx.conf test failed
[emerg] は起動できない致命的なエラー、[warn] は動作はするが注意が必要な警告です。示された行番号は、問題が見つかった位置であって、原因の位置とは限りません。よく見かけるものを、出会う頻度の高い順に並べます。
unknown directive "..."ディレクティブ名の打ち間違いか、そのディレクティブを含むモジュールが組み込まれていないことが原因です。綴りを確かめ、正しければ nginx -V の出力でモジュールが含まれているか、動的モジュールなら load_module が書かれているかを確認します。
unexpected "}" / unexpected end of file, expecting ";" or "}"直前の行のセミコロン漏れか、波括弧の対応が崩れていることが原因です。報告された行より前を見直します。ファイル末尾で報告される場合は、どこかの { が閉じられていません。エディタの括弧対応表示を使うと見つけやすくなります。
"..." directive is not allowed here書いてはいけないコンテキストにディレクティブがあります。たとえば map や upstream を server の中に書いた場合です。公式ドキュメントで各ディレクティブの「Context」欄を確認し、正しいブロックへ移します。
"..." directive is duplicate同じブロック内に、1回しか書けないディレクティブが2回あります。include したファイル同士で重複していることが多いため、nginx -T で全体を検索すると見つけやすくなります。
cannot load certificate "..." / BIO_new_file() failed証明書や鍵のパスが誤っているか、ファイルが存在しない、または読み取り権限がない状態です。Let's Encrypt の場合は live/ 配下のシンボリックリンクが正しい先を指しているかも確認します。
host not found in upstream "..."proxy_pass や upstream に書いたホスト名が、チェック時点で名前解決できません。DNS の設定やホスト名の綴りを確認します。コンテナ環境では、相手のコンテナがまだ起動していないと出ることがあります。
conflicting server name "..." on 0.0.0.0:80, ignored(warn)同じポートで同じ server_name を持つ server ブロックが2つあります。警告なので起動はしますが、後から書いた方が無視されます。sites-enabled/ に古い設定のリンクが残っているケースが典型です。
チェックを通っても失敗するケース
nginx -t で検出できない問題もあります。
- ポートが使用中: 別のプロセスが 80 や 443 を使っていると、起動時に「bind() ... failed (98: Address already in use)」になります。
sudo ss -ltnp | grep -E ':80|:443'で使っているプロセスを確認します - 実行時に決まる値: 変数を使った
proxy_passの宛先や、リクエストごとに参照されるファイルは、チェック時には検査されません - 意図と違う動作: 文法が正しくても、
locationの優先順位やadd_headerの継承で、期待した応答にならないことがあります。これはcurl -Iなどで実際の応答を見て確かめるしかありません
reload で新しい設定の適用に失敗した場合、Nginx は古い設定のまま動き続け、原因は error.log に記録されます。systemctl reload が成功と表示しても、実際には新しい設定が反映されていないことがあるため、sudo tail -n 20 /var/log/nginx/error.log もあわせて確認しておくと安心です。
事故を防ぐ手順への組み込み
チェックを人の注意力に頼らず、手順として固定しておくと、深夜の作業でも同じ品質を保てます。
# 変更前のバックアップ
sudo cp -a /etc/nginx /etc/nginx.bak-$(date +%Y%m%d%H%M)
# チェックが成功したときだけ reload する
sudo nginx -t && sudo systemctl reload nginx
&& でつなぐと、チェックが失敗した時点で reload は実行されません。Debian・Ubuntu や RHEL 系のパッケージに含まれる systemd のユニットは、起動前に nginx -t を実行する設定になっていることが多いですが、内容はディストリビューションや版で異なるため、systemctl cat nginx で確認してください(2026年10月現在)。
Docker で動かしている場合は、コンテナの中で同じコマンドを実行します。
docker exec <コンテナ名> nginx -t
docker exec <コンテナ名> nginx -s reload
設定を Git で管理しているなら、CI で公式の Nginx イメージを使って nginx -t を実行する方法もあります。ただし証明書や upstream のホスト名など、本番にしかないものはチェックが失敗するため、ダミーの証明書を用意するか、検査対象を絞る工夫が必要です。
大きな変更は、本番と同じバージョンのステージング環境でチェックと動作確認を済ませてから本番に適用してください。
まとめ
- 設定を変えたら
sudo nginx -tで「syntax is ok」と「test is successful」を確かめてから反映する nginx -Tで読み込まれた全設定を表示でき、include 漏れや重複の発見に使える(出力の扱いには注意)- エラーは種類とファイル名・行番号で示され、行番号の直前に原因があることが多い
- ポートの競合や実行時の値、意図と違う動作は
-tでは分からないため、error.logとcurl -Iで確認する nginx -t && systemctl reload nginxの形で、チェックの失敗時に反映されない手順にしておく