DevToolBox

ECONNREFUSEDETIMEDOUT の違い・切り分け

最終更新日: 2026-04-19公開日: 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秒

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.codeundefined のままで、実際のエラーコード "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 などで確認してください。

関連ツール / Related tools

関連ガイド / Related guides