「nginx: [emerg] bind() to 0.0.0.0:80 failed」の原因と解決方法

  • 作成日 2026.07.02
  • nginx
「nginx: [emerg] bind() to 0.0.0.0:80 failed」の原因と解決方法

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)

nginx を起動・再起動しようとしたときに出るこのエラー。括弧内のエラーコードによって原因が大きく異なるため、まずどちらのパターンか見分けることが解決への近道です。

本記事では以下の疑問に答えます。

  • Address already in usePermission denied の違い
  • 80番ポートを使っているプロセスの特定・終了方法
  • Apache・Docker・他の nginx プロセスとの競合の対処
  • 設定ファイルの重複 listen ディレクティブの見つけ方
  • systemd 環境での正しい再起動手順


目次

結論:先に答えを出す

# ① エラーの種類を確認(括弧内を見る)
sudo nginx -t
# (98: Address already in use)  → ポートが使用中
# (13: Permission denied)       → 権限不足

# ② 80番ポートを使っているプロセスを特定
sudo lsof -i :80
sudo ss -tlnp | grep :80

# ③ プロセスを終了
sudo kill -9 <PID>

# ④ nginx を正しい手順で再起動
sudo systemctl stop nginx
sudo nginx -t          # 設定ファイルのテスト
sudo systemctl start nginx

エラーの2つのパターンを見分ける

sudo nginx -t
# または
sudo systemctl status nginx
sudo journalctl -u nginx -n 30

エラーメッセージの括弧内を確認します。

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
                                              ^^^^^^^^^^^^^^^^^^^^^^^^
                                              → 別プロセスがポートを使用中

nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)
                                              ^^^^^^^^^^^^^^^^^^^
                                              → 権限不足(root以外で実行など)
エラーコード意味主な原因
98: Address already in useポートが既に使われている他の Web サーバー・古い nginx プロセス・Docker
13: Permission deniedポートをバインドする権限がないroot 以外で実行・SELinux・AppArmor
99: Cannot assign requested address指定したIPアドレスが存在しないlisten ディレクティブのIP指定ミス

パターン1:Address already in use(98)

原因

80番ポートをすでに別のプロセスが使用しています。よくある組み合わせ:

- Apache(apache2 / httpd)が起動している
- 別の nginx プロセスがすでに動いている(古いプロセスの残留)
- Docker コンテナが 80 番をホストにマッピングしている
- 他の Web サーバー(Caddy・lighttpd 等)
- 開発用サーバー(python -m http.server 80 等)

確認:80番ポートを使っているプロセスを特定

# lsof で確認(最も分かりやすい)
sudo lsof -i :80

# 出力例
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
apache2  1234  root   4u  IPv6  12345      0t0  TCP *:80 (LISTEN)

# ss で確認
sudo ss -tlnp | grep :80

# 出力例
LISTEN  0  511  0.0.0.0:80  0.0.0.0:*  users:(("apache2",pid=1234,fd=4))

# netstat で確認(旧来の方法)
sudo netstat -tlnp | grep :80

解決方法1:競合しているプロセスを終了する

# Apache が動いている場合
sudo systemctl stop apache2
sudo systemctl disable apache2   # 自動起動も無効化

# CentOS/RHEL系の場合
sudo systemctl stop httpd
sudo systemctl disable httpd

# 古い nginx プロセスが残っている場合
ps aux | grep nginx
sudo kill -9 <PID>

# それでも解放されない場合
sudo lsof -ti :80 | xargs sudo kill -9

解決方法2:古い nginx プロセスをすべて終了してから起動

nginx は master プロセスと worker プロセスで構成されているため、kill の仕方を間違えると一部のプロセスが残ることがあります。

# nginx の全プロセスを確認
ps aux | grep nginx
# root  1234  ... nginx: master process
# www-data  1235  ... nginx: worker process
# www-data  1236  ... nginx: worker process

# 正しい停止方法(推奨)
sudo nginx -s stop
# または
sudo systemctl stop nginx

# それでも残る場合は強制終了
sudo pkill -9 nginx

# プロセスが残っていないことを確認
ps aux | grep nginx
sudo lsof -i :80

# 起動
sudo systemctl start nginx

解決方法3:Docker コンテナが80番を使用している場合

# 80番を使っているコンテナを確認
docker ps | grep "0.0.0.0:80"

# 出力例
CONTAINER ID   IMAGE   PORTS                  NAMES
abc123def456   nginx   0.0.0.0:80->80/tcp     my-container

# コンテナを停止
docker stop abc123def456

# すべてのコンテナを確認・停止
docker ps -a
docker stop $(docker ps -q)

# docker-compose の場合
docker-compose down

解決方法4:systemd のソケットアクティベーションが原因の場合

まれに nginx.socket のような systemd ソケットユニットが先にポートを掴んでいることがあります。

# nginx 関連の socket unit を確認
systemctl list-units | grep nginx

# socket unit があれば停止
sudo systemctl stop nginx.socket
sudo systemctl disable nginx.socket

パターン2:Permission denied(13)

原因

1024番以下のポート(80・443など)をバインドするには、Linux では通常 root 権限が必要です。

よくある原因:
- nginx を root 以外のユーザーで起動しようとした
- SELinux が80番ポートへのバインドをブロックしている
- AppArmor のプロファイルが制限している
- Linux capabilities が不足している(systemd 以外で起動する場合)

確認方法

# 現在のユーザーを確認
whoami

# nginx プロセスの実行ユーザーを確認
ps aux | grep "nginx: master"
# root が master プロセスを実行している必要がある

# SELinux の状態を確認(CentOS/RHEL/Rocky Linux)
getenforce
# Enforcing / Permissive / Disabled

解決方法1:root権限で起動する

# systemctl を使う場合(推奨・自動的にroot権限で起動)
sudo systemctl start nginx
sudo systemctl restart nginx

# 直接 nginx コマンドを使う場合
sudo nginx
sudo nginx -s reload
# nginx.conf で worker プロセスのユーザーを確認
# master プロセスは root、worker プロセスは www-data 等の非特権ユーザー
user www-data;
worker_processes auto;

解決方法2:SELinux が原因の場合(CentOS/RHEL/Rocky Linux)

# SELinux のログを確認
sudo ausearch -m avc -ts recent | grep nginx
sudo sealert -a /var/log/audit/audit.log 2>/dev/null | grep -A 5 nginx

# nginx が80番ポートにバインドする権限があるか確認
sudo semanage port -l | grep http_port_t
# http_port_t  tcp  80, 81, 443, ...

# 別のポート(例:8888)を使いたい場合に SELinux ポリシーを追加
sudo semanage port -a -t http_port_t -p tcp 8888

# SELinux を一時的に Permissive にして切り分け(本番では非推奨)
sudo setenforce 0
sudo systemctl restart nginx
# → 起動すれば SELinux が原因と確定
sudo setenforce 1  # 元に戻す

解決方法3:非特権ユーザーで1024番以下を使いたい場合

# Linux capabilities で特定のバイナリに権限を付与
sudo setcap 'cap_net_bind_service=+ep' /usr/sbin/nginx

# 確認
getcap /usr/sbin/nginx
# /usr/sbin/nginx = cap_net_bind_service+ep

# authbind を使う方法
sudo apt install authbind
sudo touch /etc/authbind/byport/80
sudo chown www-data /etc/authbind/byport/80
sudo chmod 700 /etc/authbind/byport/80
authbind nginx

解決方法4:1024番以上のポートを使う(開発環境向け)

本番環境でなければ、80番以外のポートを使うのも有効な選択肢です。

# /etc/nginx/sites-available/default
server {
    listen 8080;   # 80 → 8080 に変更
    server_name example.com;
    ...
}
sudo nginx -t
sudo systemctl restart nginx

# 確認
curl http://localhost:8080

パターン3:Cannot assign requested address(99)

nginx: [emerg] bind() to 192.168.1.100:80 failed (99: Cannot assign requested address)

原因

listen ディレクティブで指定したIPアドレスがサーバーに存在しない場合に発生します。

確認方法

# サーバーの実際のIPアドレスを確認
ip addr show
hostname -I

# nginx.conf の listen ディレクティブを確認
sudo grep -r "listen" /etc/nginx/sites-enabled/
sudo grep -r "listen" /etc/nginx/conf.d/

解決方法

# ❌ 存在しないIPを指定している
server {
    listen 192.168.1.100:80;  # このIPがサーバーに割り当てられていない
}

# ✅ 0.0.0.0 ですべてのインターフェースで待ち受ける
server {
    listen 0.0.0.0:80;
    # または単に
    listen 80;
}

# ✅ 実際に割り当てられているIPを指定する
server {
    listen 10.0.0.5:80;  # ip addr show で確認した実際のIP
}

設定ファイルの重複 listen が原因の場合

複数の設定ファイルで同じポートを listen していると、起動時に競合してエラーになることがあります。

確認方法

# すべての設定ファイルで listen ディレクティブを横断検索
sudo grep -rn "listen" /etc/nginx/sites-enabled/
sudo grep -rn "listen" /etc/nginx/conf.d/

# 出力例(重複している場合)
/etc/nginx/sites-enabled/default:2:    listen 80 default_server;
/etc/nginx/sites-enabled/mysite.conf:2:    listen 80 default_server;
#                                                      ^^^^^^^^^^^^^^
#                                          default_server が2つ存在するとエラー
nginx: [emerg] a duplicate default server for 0.0.0.0:80 in /etc/nginx/sites-enabled/mysite.conf:2

解決方法

# 不要な設定ファイルを無効化
sudo rm /etc/nginx/sites-enabled/default
# または
sudo unlink /etc/nginx/sites-enabled/default

# default_server を1つの設定ファイルだけに限定する
sudo vi /etc/nginx/sites-enabled/mysite.conf
# 1つのファイルだけに default_server を残す
server {
    listen 80 default_server;
    server_name _;
    ...
}

# 他のファイルは default_server を付けない
server {
    listen 80;
    server_name example.com;
    ...
}
# 設定をテストしてから反映
sudo nginx -t
sudo systemctl reload nginx

Docker / docker-compose での nginx 起動エラー

# ホストの80番が他のプロセスに使われている場合
docker: Error response from daemon: driver failed programming external connectivity
on endpoint nginx: Bind for 0.0.0.0:80 failed: port is already allocated.
# ホスト側で80番を使っているプロセスを確認
sudo lsof -i :80
sudo ss -tlnp | grep :80

# ホストの nginx・apache を停止する
sudo systemctl stop nginx
sudo systemctl stop apache2

# または docker-compose.yml のポートマッピングを変更
# docker-compose.yml
services:
  web:
    image: nginx
    ports:
      - "8080:80"   # ホスト側を 8080 に変更
# 別のコンテナが80番を専有している場合
docker ps | grep ":80->"
docker stop <コンテナID>

docker-compose up -d

設定変更後の正しい反映手順

エラーが発生したら、以下の手順で確実に解決状況を確認しながら進めます。

# Step 1:設定ファイルの構文チェック(起動せずに確認できる)
sudo nginx -t
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful

# Step 2:現在の nginx プロセス・競合プロセスを確認
ps aux | grep nginx
sudo lsof -i :80

# Step 3:問題があれば対処(プロセス終了・設定修正)

# Step 4:nginx を再起動
sudo systemctl restart nginx

# Step 5:起動できたか確認
sudo systemctl status nginx
curl -I http://localhost

トラブルシューティング

nginx -t は成功するのに起動できない

# nginx -t は構文チェックのみで、ポートの競合は検出しないことがある
sudo nginx -t
# ↑ これが成功しても

sudo systemctl start nginx
# ↑ これは失敗することがある(ポート競合等の実行時エラーのため)

# journalctl で実際のエラーを確認
sudo journalctl -u nginx -n 50 --no-pager

systemctl restart で固まる・タイムアウトする

# nginx のプロセスが完全に終了していない状態で再起動しようとしている
sudo systemctl status nginx

# 強制的にすべて終了してから起動
sudo pkill -9 nginx
sleep 2
sudo systemctl start nginx

IPv6 だけ失敗する場合

nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
# IPv6 を使っているプロセスを確認
sudo lsof -i6 -P -n | grep :80
sudo ss -tlnp6 | grep :80

# IPv6 を無効化したい場合
server {
    listen 80;
    # listen [::]:80;  ← この行をコメントアウトすると IPv6 無効化
}

コンテナ内で何度も再発する

# Dockerfile・entrypoint で前回のプロセスが残らないようにする
# entrypoint.sh の例
#!/bin/bash
# 念のため既存の nginx プロセスを掃除してから起動
pkill -9 nginx 2>/dev/null || true
exec nginx -g 'daemon off;'

よくある質問(FAQ)

Q1. Address already in usePermission denied を見分けるコツは?

エラーメッセージの括弧内の数字と説明文を見ます。(98: Address already in use) ならポート競合、(13: Permission denied) なら権限不足です。sudo nginx -t を実行すると同じエラーが表示されます。

Q2. nginx を再起動するときは restartreload どちらを使えばいいですか?

設定ファイルの変更だけなら reload(無停止で設定を反映)を使います。ポート競合などのエラーで起動自体ができていない場合は restart を使い、それでも失敗する場合は stop → 原因調査 → start の順で対処します。

sudo systemctl reload nginx   # 設定変更の反映(推奨・無停止)
sudo systemctl restart nginx  # 完全に再起動
sudo nginx -s reload          # nginx コマンドでの reload

Q3. 80番ポートをどうしても使いたいのに権限がない場合は?

sudo で起動するのが基本です。systemd のサービスとして登録されている nginx は通常 root 権限で master プロセスが起動するため、sudo systemctl start nginx であれば問題なく80番を使えます。直接 nginx コマンドを使う場合は sudo nginx としてください。

Q4. Apache と nginx を同じサーバーで両方使いたい場合は?

ポートを分けて共存させます。

# nginx を 80・443 で動かし、Apache を別ポートで動かす
# /etc/apache2/ports.conf
Listen 8080

# nginx でリバースプロキシしてApacheに転送する構成が一般的
server {
    listen 80;
    location /app/ {
        proxy_pass http://127.0.0.1:8080/;
    }
}

Q5. クラウド環境(AWS EC2 等)特有の注意点はありますか?

セキュリティグループで80番ポートが開いているかも確認してください。bind() failed 自体はサーバー内部のエラーですが、外部からアクセスできない場合はセキュリティグループ・ファイアウォール(ufwfirewalld)の設定も合わせて確認します。

# ufw の確認(Ubuntu)
sudo ufw status
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# firewalld の確認(RHEL系)
sudo firewall-cmd --list-all
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload

まとめ

nginx: [emerg] bind() to 0.0.0.0:80 failed はエラーコードによって対処が変わります。

(98: Address already in use)
  → 80番ポートを使っているプロセスを特定して終了
    sudo lsof -i :80
    sudo systemctl stop apache2  # 例
    sudo systemctl restart nginx

(13: Permission denied)
  → root権限で起動する・SELinuxを確認
    sudo systemctl start nginx
    sudo semanage port -l | grep http_port_t

(99: Cannot assign requested address)
  → listen ディレクティブのIP指定を確認
    listen 0.0.0.0:80;  # または単に listen 80;

確認の基本フロー:

sudo nginx -t                  # 設定の構文チェック
sudo lsof -i :80                # ポート使用状況の確認
sudo journalctl -u nginx -n 50  # 詳細なエラーログ確認

参考リンク

公式ドキュメント

関連記事(本サイト)


本記事は2026年6月時点の情報をもとに、Ubuntu 24.04 LTS・nginx 1.24.x・Rocky Linux 9 での動作確認に基づき作成しています。バージョンや環境によって挙動が異なる場合があるため、最新情報は公式ドキュメントをご確認ください。