「localhostで接続が拒否されました(ERR_CONNECTION_REFUSED)」は、ブラウザがアクセスしたポート番号で、待ち受けているプログラムが見つからなかったときに表示されるエラーです。つまり、「サーバーが起動していない」か、「サーバーは起動しているが、ブラウザが別の場所(ポート・アドレス)にアクセスしている」かのどちらかです。

このエラーは、原因がいくつも考えられるため、順番に切り分けるのが解決への近道です。この記事では、確認する順番に沿って、よくある原因と確認コマンド、解決方法を解説します。

まず確認:エラーの種類

似たメッセージでも、意味が違います。ブラウザに表示されたエラーコードを確認してください。

エラー 意味 主な原因
ERR_CONNECTION_REFUSED(接続が拒否されました) そのポートで待ち受けているプログラムがない サーバーが止まっている、ポート番号の違い
ERR_CONNECTION_TIMED_OUT(応答時間が長すぎます) 応答が返ってこない ファイアウォール、別のマシンのアドレス
ERR_EMPTY_RESPONSE(データが送信されませんでした) つながったが、何も返ってこない サーバー側のエラー、httpとhttpsの違い
ERR_SSL_PROTOCOL_ERROR 暗号化の通信ができない httpのサーバーにhttpsでアクセスしている
404 Not Found サーバーにはつながったが、そのページがない URLのパスの違い

「接続が拒否されました」なら、サーバーまでの到達に問題があります。以下の順番で確認します。

原因の切り分け(確認する順番)

順番 確認すること 確認方法
1 サーバーは起動しているか ターミナルにエラーが出ていないか
2 ポート番号は合っているか サーバーの起動メッセージとURLを見比べる
3 そのポートで待ち受けているか lsof・netstat で確認
4 httpとhttpsを間違えていないか URLの先頭を確認
5 IPv4とIPv6の食い違いはないか 127.0.0.1 で試す
6 Docker・WSL2・仮想環境の中ではないか ポートの公開と待ち受けアドレス
7 ファイアウォール・セキュリティソフト 一時的に確認

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「localhostで接続が拒否されましたの原因と解決方法」

1. サーバーが起動していない

最も多い原因です。

  • ターミナルを閉じた、パソコンをスリープさせた後に、サーバーが止まっている
  • 起動時にエラーが出て、起動に失敗している(ターミナルの最後を見るとエラーが出ている)
  • npm run dev などを実行したターミナルと、別のターミナルを見ている

サーバーを起動したターミナルを確認し、「Local: http://localhost:5173/」「Listening on port 3000」のような起動メッセージが表示されているかを確認します。エラーが出ている場合は、そのエラーを先に解決します。

2. ポート番号が違う

開発サーバーのツールによって、既定のポート番号が違います。サーバーの起動メッセージに表示されたURLを、そのまま使うのが確実です。

ツール 既定のポート
Vite(React・Vueなど) 5173
Next.js 3000
Create React App 3000
Angular 4200
Django 8000
Flask 5000
Spring Boot・Tomcat 8080
Rails 3000
PHP組み込みサーバー 指定したポート

Viteなどは、既定のポートが使用中だと、自動で別の番号(5174など)で起動します。いつもと同じURLを開くと、つながらないことがあります。

3. そのポートで待ち受けているか確認する

実際に、どのプログラムがどのポートで待ち受けているかを確認します。

# Mac・Linux
lsof -i :3000 -sTCP:LISTEN
:: Windows
netstat -ano | findstr :3000

何も表示されなければ、そのポートで待ち受けているプログラムはありません。サーバーが起動していないか、別のポートで起動しています。

コマンドラインから直接アクセスしてみるのも有効です。

curl -v http://localhost:3000

Connection refused と表示されれば、ブラウザの問題ではなく、サーバー側に原因があることがわかります。curlでは表示されるのにブラウザで表示されない場合は、次の「https」や「ブラウザの設定」を疑います。

4. httpsに自動で切り替わっている

http://localhost:3000 と入力したのに、アドレスバーが https://localhost:3000 に変わっている場合、ブラウザが以前の記録(HSTS)に従って、自動でhttpsに切り替えています。開発サーバーの多くはhttpで動いているため、つながりません。

以前、localhostで別のアプリをhttpsで動かしたことがあると、起きることがあります。

Chromeでの解消方法

  1. アドレスバーに chrome://net-internals/#hsts と入力する
  2. 「Delete domain security policies」に localhost と入力し、「Delete」を押す
  3. ブラウザを再読み込みする

シークレットウィンドウで開いてつながる場合も、ブラウザに残った設定が原因の可能性が高いといえます。

5. IPv4とIPv6の食い違い

localhost という名前は、IPv4の 127.0.0.1 と、IPv6の ::1 のどちらにも対応しています。サーバーが片方だけで待ち受け、ブラウザや別のプログラムがもう片方にアクセスすると、「接続が拒否されました」になります。

状況 起きること
サーバーが 127.0.0.1 だけで待ち受けている ::1 でアクセスされると、つながらない
サーバーが ::1 だけで待ち受けている 127.0.0.1 でアクセスされると、つながらない

確認方法:URLを http://127.0.0.1:3000 に変えて試します。つながる場合は、この食い違いが原因です。

Node.js 17以降では、localhost をどちらのアドレスとして扱うかが、OSの設定の順番に従うように変わったため、開発サーバーとAPIのプロキシ設定の間でこの問題が起きやすくなりました。プロキシの接続先を http://localhost:8080 から http://127.0.0.1:8080 に変える、またはサーバーの待ち受けアドレスを明示すると解決します。

6. Docker・WSL2・仮想環境の中で動いている

Dockerのコンテナで動かしている

コンテナの中のサーバーにアクセスするには、ポートの公開と、アプリが外部からの接続を受け付ける設定の両方が必要です。

docker ps    # PORTS に 0.0.0.0:3000->3000/tcp のように表示されているか
確認すること 対処
ポートを公開しているか docker run -p 3000:3000 または compose の ports:
アプリが 0.0.0.0 で待ち受けているか 127.0.0.1 で待ち受けていると、コンテナの外からは届かない

アプリの待ち受けアドレスは、ツールごとに指定します(例:Viteは --host、Flaskは --host=0.0.0.0、Djangoは runserver 0.0.0.0:8000)。

WSL2で動かしている

WSL2(Windows上のLinux)で起動したサーバーは、通常はWindowsのブラウザから localhost でアクセスできます。つながらない場合は、次を確認します。

  • サーバーを 0.0.0.0 で待ち受けるように起動する
  • WSLを再起動する(PowerShellで wsl --shutdown を実行し、開き直す)
  • WSL側のIPアドレス(hostname -I で確認)で直接アクセスしてみる

スマートフォンや別のパソコンからアクセスしている

localhost は「自分自身」を指す名前です。スマートフォンから http://localhost:3000 を開くと、スマートフォン自身にアクセスしてしまいます。別の端末から確認するには、開発しているパソコンのIPアドレス(例:http://192.168.1.10:3000)を使い、サーバーを 0.0.0.0 で待ち受けるように起動します。

7. ファイアウォール・セキュリティソフト

自分のパソコンの中の通信(localhost)がファイアウォールで止められることは多くありませんが、会社のパソコンのセキュリティソフトが、特定のポートやプログラムの通信を制限している場合があります。他の原因に当てはまらない場合は、管理者に確認します。

ツール別:よくある原因

ツール よくある原因 対処
Vite ポートが使用中で、自動で5174などに変わっている 起動メッセージのURLを使う
Vite(Docker・WSL) localhostだけで待ち受けている vite --host
Next.js ビルドエラーで起動していない ターミナルのエラーを確認
Flask(Mac) 5000番をAirPlayが使っている flask run --port 5001
Spring Boot 起動中にエラーで停止している(DB接続など) ログの最後のエラーを確認
XAMPP・MAMP Apacheが起動していない、ポートが80・8888 コントロールパネルで起動状態を確認

よくある質問

Q. 昨日まで表示できていたのに、急につながらなくなりました。 A. サーバーが止まっている可能性が最も高いです。パソコンの再起動やスリープで、開発サーバーは停止します。起動し直して、起動メッセージのURLを開いてください。

Q. 127.0.0.1とlocalhostは同じですか? A. 多くの場合は同じ場所を指しますが、localhostはIPv6の ::1 も指すことがあるため、厳密には同じではありません。つながらないときは、127.0.0.1 で試すと原因の切り分けに役立ちます。

Q. 「このサイトにアクセスできません」と表示されます。 A. これはChromeの共通の画面で、その下に表示されているエラーコード(ERR_CONNECTION_REFUSEDなど)で原因が変わります。エラーコードを確認して、この記事の表と照らし合わせてください。

Q. ポート番号を省略して http://localhost だけで開くとどうなりますか? A. httpなら80番、httpsなら443番に接続します。開発サーバーの多くは3000番や8080番などで動いているため、ポート番号を付ける必要があります。

まとめ

  • 「接続が拒否されました」は、そのポートで待ち受けているプログラムがないという意味
  • 確認の順番は、起動しているか → ポート番号 → 待ち受けの確認(lsof・netstat)→ https → IPv4/IPv6 → Docker・WSL2
  • 起動メッセージのURLをそのまま使う。Viteなどは自動でポートを変えることがある
  • アドレスバーが勝手にhttpsになるなら、ChromeのHSTSの設定を削除する
  • 127.0.0.1で試してつながるなら、IPv4とIPv6の食い違い
  • Docker・WSL2では、ポートの公開と0.0.0.0での待ち受けを確認する

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「localhostで接続が拒否されましたの原因と解決方法」

株式会社RJCでは、エラーの原因を一つずつ切り分けて考える力を、エンジニアの大切な基礎だと考えています。こうした知識を仲間と共有しながら、一緒に成長を楽しんでいます。

株式会社RJC ― SI事業・SES事業・AI駆動開発。未経験からエンジニアに育てるのが得意な会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?