DevToolBox

ECONNREFUSED と ETIMEDOUT の違い・切り分け

最終更新日: 2026-09-16公開日: 2026-04-19執筆: DevToolBox編集部

どちらも「接続できない」ように見えますが、発生レイヤが違います。違いを押さえると 診断時間が一桁縮みます。

Both look like "cannot connect", but they happen at different TCP stages. Knowing which means which cuts your triage time drastically.

TL;DR

1. TCP レベルで何が起きているか / At the TCP layer

エラー / ErrorTCP 動作発生時間
ECONNREFUSEDSYN → RST (リセット)即時 (数ms)
ETIMEDOUTSYN → 応答なしOS 既定で 21〜75秒
図1: ECONNREFUSEDとETIMEDOUTが発生する層の違い
ECONNREFUSEDとETIMEDOUTが発生する通信経路上の段階の違いクライアントからDNS、ネットワーク経路、宛先ホストのポートまでの経路上で、ECONNREFUSEDはホストまで届きポートで即座に拒否されるのに対し、ETIMEDOUTはネットワーク経路の途中で応答が失われることを示す図クライアントDNS解決ネットワーク経路宛先ホストのアプリ / OS名前解決ルーター・FW等TCPスタックとポートECONNREFUSED: ホストまで届きポートで即座に拒否(RST)ETIMEDOUT: ここで応答が失われ、OS既定の秒数だけ待つECONNREFUSEDは宛先到達済み、ETIMEDOUTは途中経路で応答が消えている可能性が高い

2. 切り分けコマンド / Diagnose

# 1. DNS 解決できるか
nslookup example.com

# 2. TCPで到達できるか
nc -vz example.com 443     # Succeeded = 到達、 timed out = ETIMEDOUT相当
curl -v https://example.com

# 3. ローカルの listen 確認
ss -ltnp | grep 3000       # Linux
lsof -i :3000              # macOS

3. よくある原因 / Common causes

エラー原因対処
ECONNREFUSED 127.0.0.1:3000サーバ未起動 / 別IFにバインドlisten 確認、0.0.0.0 にバインド
ECONNREFUSED (Docker)コンテナ名/ネットワーク誤りdepends_on とサービス名で接続
ETIMEDOUT (外部API)ファイアウォール / egress制限VPC の outbound rule を確認
ETIMEDOUT (Lambda)VPC 設定のNAT欠落NAT Gateway / VPC Endpoint 追加

4. Node.js 側でのハンドリング / Handling in Node.js

try {
  await fetch("https://api.example.com", { signal: AbortSignal.timeout(5000) });
} catch (e) {
  if (e.cause?.code === "ECONNREFUSED") console.error("port closed");
  else if (e.cause?.code === "ETIMEDOUT" || e.name === "TimeoutError") console.error("no response");
  else throw e;
}

実際に検証してみると / What we found when we actually tested this

上のコード例が e.cause?.code を確認しているのには理由があります。実際に Node.js v24.14.1 で、誰も listen していないポートに対して fetch("http://127.0.0.1:54321", { signal: AbortSignal.timeout(3000) }) を実行したところ、e.code は undefined のままで、実際のエラーコード "ECONNREFUSED" は e.cause.code に入っていました。

name: TypeError
message: fetch failed
code: undefined
cause code: ECONNREFUSED
cause: Error: connect ECONNREFUSED 127.0.0.1:54321

これは Node.js の fetch が undici 実装をベースにしており、低レベルのネットワークエラー情報を cause プロパティに格納する設計になっているためです。

There is a reason the example above checks e.cause?.code: in our Node.js v24.14.1 test, e.code remained undefined, while the actual "ECONNREFUSED" code appeared in e.cause.code. This is because Node.js fetch is based on undici, which stores low-level network error details in the cause property.

5. English summary

ECONNREFUSED means the TCP stack on the target host replied with RST — the host is reachable but nothing is listening on that port. ETIMEDOUT means no reply came back at all, usually a firewall silently dropping packets or a network partition. Diagnose in this order: DNS → nc -vz host port → local listen check. For Lambda and container environments, ETIMEDOUT often points to missing NAT or wrong service-to-service networking.

よくある質問 / FAQ

ECONNREFUSED と ETIMEDOUT の違いは?
ECONNREFUSED は宛先ホストまで届いたがポートが開いていない(即時 RST 応答)。ETIMEDOUT は宛先から応答が一切ない(ファイアウォール遮断や経路断、オフライン)を意味します。
What's the difference between ECONNREFUSED and ETIMEDOUT?
ECONNREFUSED means the host responded but the port is closed (TCP RST). ETIMEDOUT means no response at all — typically a firewall dropping packets or a network partition.
localhost:3000 で ECONNREFUSED
サーバがそのポートで listen していないか、別IF(::1 vs 127.0.0.1)にバインドしています。listen 状況を lsof -i :3000 などで確認してください。

参考資料 / References

関連ツール / Related tools

関連ガイド / Related guides