※購入先、ダウンロードへのリンクにはアフィリエイトタグが含まれており、それらの購入や会員の成約、ダウンロードなどからの収益化を行う場合があります。

upstream request timeoutで504が急増した原因はどこ?層別切り分けと最短復旧の手順

「504 Gateway Timeout」が急に増え、レスポンスやログに「upstream request timeout」。この瞬間に厄介なのは、原因がアプリの遅延だけとは限らず、ロードバランサー、Ingress、Nginx、Envoy、サービスメッシュなど“途中の中継”のどこでも起こり得る点です。闇雲にタイムアウトを延長すると、待ちリクエストが積み上がって障害を拡大させることもあります。

本記事では、まず最初の15分で「どの層が504を返しているか」を確定し、connect/read/routeといった待ち時間の種類を分解して、原因を最短で絞り込みます。さらに、Nginx・Envoy・GKE internal Ingressなど環境別に、確認すべきログと設定の対応関係を整理し、暫定復旧の判断基準から再発防止の観測テンプレまで、次回も迷わない形でまとめます。

※本コンテンツは「記事制作ポリシー」に基づき、正確かつ信頼性の高い情報提供を心がけております。万が一、内容に誤りや誤解を招く表現がございましたら、お手数ですが「お問い合わせ」よりご一報ください。速やかに確認・修正いたします。

目次

upstream request timeoutで何が起きているのか

まず押さえるべき結論は「中継が待ち切れなかった」

upstream request timeoutは、多くの場合「クライアントが遅い」ではなく、クライアントとアプリの間にいる“中継(ロードバランサー、プロキシ、Ingress、サービスメッシュなど)”が、上流(upstream)の応答を期限内に受け取れず、処理を打ち切ったことを示すサインです。
この結果として、HTTPの世界では504 Gateway Timeoutとして表に出ることがよくあります。504は「ゲートウェイ/プロキシが上流サーバーから期限内に有効な応答を受け取れなかった」状態を指します。

ここで重要なのは、upstream request timeoutという文言が出た瞬間に「アプリが遅い」と決めつけないことです。中継が複数段ある現代の構成では、どの中継がタイムアウトしたのかで原因も対策も変わります。

15分でやるべきことは「どの層が504を返したか」の確定

障害対応中に最も価値があるのは、詳細な理屈よりも「次に何を見ればよいか」が一瞬で分かることです。まずは以下の問いに答えるところから始めます。

  • 504(またはupstream request timeout)を返しているのは、どの装置/プロセス
    例:Cloud Load Balancerなのか、Nginxなのか、Envoyなのか、Ingressなのか

  • それは「上流に接続できない」のか「接続はできるが返ってこない」のか

  • 特定のエンドポイントだけか、全体か。デプロイ直後だけか、常時か

この確定ができれば、調査は迷走しません。


upstream request timeoutの切り分けを最短で終える手順

最初の15分チェックリスト(緊急対応テンプレ)

以下は、現場で“最初に見るべき順番”を固定するためのテンプレです。障害対応のたびに順番が揺れると、判断が遅れます。

  1. ユーザー影響の把握

    • 影響する機能/APIはどれか(例:/api/orders だけ、全APIなど)

    • 発生開始時刻はいつか(デプロイ/設定変更と相関があるか)

  2. 504を返している主体の特定

    • ブラウザのレスポンスヘッダ、LBのアクセスログ、プロキシのアクセスログを確認

    • 可能ならレスポンス本文(例:upstream request timeout)も採取

  3. ログの“同一リクエスト”突合

    • request-id / trace-id / x-request-id などがあるなら、それで追跡

    • ない場合は「時刻+URL+クライアントIP」で近似

  4. 上流到達性の確認(接続問題の除外)

    • DNS、ルーティング、セキュリティ(FW/SG/NetworkPolicy)

    • 上流Pod/VMが生存しているか(readyか、リスタートしていないか)

  5. 遅延の正体を“分解”

    • connectが遅いのか、応答開始が遅いのか、途中が止まるのか

  6. 暫定復旧の判断

    • タイムアウト延長で止血できるか(悪化兆候がないか)

    • それとも流量制御/リトライ抑制/ロールバックが先か

「どこで遅いか」を分解する:connect / send / read / route

タイムアウトは一括りにされがちですが、実際には「何を待っているか」が異なります。ここを分解できると、原因が急速に絞れます。

  • connect:上流へTCP接続を張るまで
    典型原因:DNS不調、ルーティング、セキュリティ、上流枯渇、SYN再送

  • send:上流へリクエストを送る間
    典型原因:大きいボディ、帯域不足、バックプレッシャー

  • read:上流からレスポンスを受信する間(無音時間含む)
    典型原因:アプリ処理遅延、DB待ち、外部API待ち、ストリーミング中断

  • route(Envoy等):下流リクエストを受け取り終えてから、上流の完全な応答を得るまで
    典型原因:上流処理が既定値より長い、あるいは上流が返せない

特にEnvoyのroute timeoutは、「下流リクエストを最後まで受け取ってから」タイマーが始まる点が重要です。アップロード中に切れる問題と、アップロード後の処理遅延は切り分け方が違います。

症状→疑う層→次アクション

以下の表は、障害時に“読む順番”が揺れないようにするためのものです。

よくある見え方 まず疑うこと 次アクション(最短)
クライアント 画面が固まる/通信切断 クライアント側タイムアウト クライアント設定値と実測レイテンシ確認
外側LB/CDN 504がLBから返る 上流到達性、LB側タイムアウト LBログで上流エラー種別/レイテンシ確認
Ingress/Proxy upstream request timeout/504 connectかreadか、設定既定値 直下のプロキシログ(upstream_response_time等)確認
Service Mesh EnvoyでUT/504 route timeout、上流準備不足 Envoyアクセスログの応答フラグ確認、ルート設定確認
アプリ 遅い/スレッド枯渇 ロック/外部API/DB APM、スロークエリ、スレッドプール、キュー長
DB/外部API スロークエリ/接続遅延 インデックス、負荷、レート制限 スローログ、待機イベント、依存先SLA確認

upstream request timeoutをNginxで疑うときの確認点と設定対応

Nginxで最初に見るログ項目(例)

Nginxをリバースプロキシとして使っている場合、設定を触る前に「ログが何を語っているか」を見ます。代表的には以下のような情報が役に立ちます(カスタムログフォーマットに依存します)。

  • ステータス(504/499/502など)

  • request_time(全体にかかった時間)

  • upstream_connect_time(接続にかかった時間)

  • upstream_header_time(ヘッダ受信まで)

  • upstream_response_time(応答全体)

  • upstream_addr(どの上流に当たったか)

これらが取れていない場合は、恒久対策として「次回の障害対応を早める」意味でも、ログを整備する価値があります。

proxy_connect_timeout / proxy_send_timeout / proxy_read_timeoutの役割

Nginxの代表的タイムアウトは、待っている対象が異なります。特にproxy_read_timeoutは誤解されやすいため、connectと分けて理解することが重要です。

ディレクティブ 何を待つか ありがちな誤解 症状の典型
proxy_connect_timeout 上流へ接続が確立するまで 「アプリが遅い」と混同 上流へ到達できず短時間で失敗
proxy_send_timeout 上流へリクエスト送信中 readと混同 大きいボディ送信で詰まる
proxy_read_timeout 上流からの受信が一定時間進まない connectと混同 上流が返さない/途中で止まる
send_timeout(参考) クライアントへ送る送信 upstreamとは別 下流送信が遅い

ここでのポイントは、connectが遅いならネットワーク/到達性readが遅いなら上流処理/DB/外部APIと、疑う方向が変わる点です。

「延長で止血」する前に確認すべき危険サイン

タイムアウトを伸ばすと、一見“治った”ように見えます。しかし、上流が詰まっている状態で延長すると、待ちリクエストが増えてワーカー/コネクションを占有し、障害が拡大することがあります。延長前に、次の危険サインを確認してください。

  • 直近で同時接続数ワーカー使用率が張り付いている

  • キュー長(アプリ側のリクエスト待ち、ジョブ待ち)が増え続けている

  • 依存先(外部API/DB)の遅延が同時刻に悪化している

  • リトライが多く、同じリクエストが重複していそう

  • 504が出る前からp95/p99レイテンシが急上昇している

この場合、延長より先に「流量制御」「リトライ抑制」「ロールバック」「依存先の隔離(サーキットブレーカー)」の方が安全なことがあります。


upstream request timeoutをEnvoyやIstioで疑うときの確認点と設定対応

Envoyのroute timeoutは「上流の完全応答」を待つ(開始条件が重要)

Envoy公式の説明として、route timeoutは「Envoyが上流から完全なレスポンスを受け取るまで待つ時間」であり、さらに「下流のリクエストストリームを全て受信してから」タイムアウトが開始する、とされています。
この仕様は、次のような誤解を防ぎます。

  • 誤解1:アップロード中に切れる → route timeoutが原因
    実際には、アップロード中は別のタイムアウトや下流側制限が疑わしい

  • 誤解2:処理が遅いだけ → とりあえず60秒に伸ばす
    実際には、上流の詰まりが悪化するリスクがある

Envoyアクセスログの「応答フラグ(UTなど)」を読み解く

Envoy系では、ログに短いフラグが出ることがあります。例えば、UTは「Upstream request timeout(504とセット)」として説明されることがあります(環境やログ設定で表示は異なります)。
ログにフラグが出る場合は、次の整理が有効です。

  • UT:上流応答を待ち切れなかった(route/stream系のタイムアウトが絡む可能性)

  • 上流接続エラー系:到達性、コネクションプール、上流枯渇

  • リセット系:上流が途中で切った、あるいはメッシュが切った

Istio環境では「どこでタイムアウトを設定しているか」を固定する

IstioはEnvoyをデータプレーンとして使いますが、タイムアウトは複数箇所で設定され得ます(アプリ、IngressGateway、VirtualService、DestinationRule、クライアント側など)。
そのため、まず次を固定します。

  • タイムアウトを管理する“正”はどこか(例:VirtualServiceのtimeoutを基準)

  • IngressGatewayとサイドカーの双方に設定があるか

  • クライアント側(SDK/ブラウザ)のタイムアウトが先に切っていないか

公式タスクでも、ルートにtimeoutを設定して挙動を確認する流れが示されています。

リトライとタイムアウトを同時に増やすと「詰まり」が増幅する

障害時にやりがちな組み合わせが、タイムアウト延長+リトライ増加です。
リトライは「一時的な失敗」には効きますが、上流が遅延している状況では、同じ処理が重複して負荷を押し上げ、さらに遅延が増える悪循環になり得ます。

  • 上流が遅い(処理能力不足)のにリトライ → さらに上流が詰まる

  • 冪等でないAPIにリトライ → 二重処理/二重課金の事故

したがって、恒久対策としては「タイムアウトをどこまで許容するか」だけでなく、「リトライ対象を何に限定するか」「冪等性をどう担保するか」までセットで設計するのが安全です。


upstream request timeoutがGKE IngressやKubernetesで出るときの見方

GKE internal Ingressでは“Envoyが中継する”ことがある

GKEの内部Ingress(内部Application Load Balancer)で、レスポンスとして「504 Gateway Timeout: upstream request timeout」が現れるケースがあり、公式ドキュメントでは、その理由としてinternal Application Load Balancer宛のトラフィックがproxy-only subnet範囲のEnvoyプロキシで中継されることが説明されています。
つまり、ここでのupstream request timeoutは、アプリのログではなく中継(Envoy)側のタイムアウトである可能性が高く、観測点を誤ると迷走します。

この場合の最短手順は次の通りです。

  1. internal Ingress経路かどうか確認(どのLB/Ingressか)

  2. その経路がEnvoy中継になる条件(proxy-only subnet等)を確認

  3. Envoy相当のログ/メトリクス(あるいはLB側ログ)でtimeoutを確認

  4. 上流サービス(Pod/NEG等)の準備不足・到達性・遅延を切り分け

Kubernetes特有の「準備不足」パターン(デプロイ直後だけ増える)

Kubernetesでは、Podが生存していても“すぐ応答できる”とは限りません。特に以下は頻出です。

  • readinessが通っていないのに流入が始まっている(設定/運用不整合)

  • startupに重い初期化(マイグレーション、キャッシュ構築、外部APIへの同期)をしている

  • ローリング更新で同時に落ちる割合が高く、瞬間的にキャパが不足する

症状が「デプロイ直後だけ」「新しいPodだけ」に偏るなら、タイムアウト延長より先に**起動シーケンスの整備(startup/readinessの設計)**を疑う方が恒久的です。

依存先がボトルネックの場合、Ingress設定だけでは解決しない

upstream request timeoutは中継で起きますが、根本は上流(アプリ/DB/外部API)にあります。以下のような状況は、Ingressの設定をいじっても解消しません。

  • DBのスロークエリ(インデックス不足、ロック競合、接続枯渇)

  • 外部APIのレート制限や遅延(再試行が逆効果)

  • アプリのスレッドプール枯渇(待ち行列が増える)

この場合は、まず“遅延の正体”をAPMやスローログで掴み、処理を短くする方向へ進むべきです。


upstream request timeoutの対処法:暫定復旧と恒久対策を分ける

暫定復旧で選べる手段(危険度順)

暫定復旧は「ユーザー影響を止める」ことが目的です。ただし、手段には危険度があります。ここでは一般的な傾向として、危険度が上がるほど副作用が増える前提で整理します。

  1. ロールバック(直前の変更が原因の可能性が高い場合は最速)

  2. 流量制御(レート制限、機能フラグで重い処理を止める)

  3. 依存先の隔離(外部API呼び出しを止め、代替応答を返す)

  4. リトライ抑制(クライアント/プロキシ/メッシュのリトライを限定)

  5. タイムアウト延長(症状が遅延のみで、待ちが増えても破綻しない場合)

タイムアウト延長は最後のカードになりがちです。延長するなら、対象を絞り、上限を決め、監視を同時に強化することが重要です。

暫定対応か恒久対策か:判断チェック表

次の表で「延長して良い状況」と「延長すると悪化しやすい状況」を整理します。

観測 状況 推奨
p95/p99が少し伸びた程度 上流は捌けている ルート限定で小幅延長は検討可
依存先遅延が一時的 外部APIの瞬間遅延 リトライ条件最適化+短期延長は可
ワーカー/接続が張り付き 待ちが溜まっている 延長は悪化しやすい(流量制御優先)
キュー長が増加し続ける 処理能力不足 延長より性能改善/スケール/設計変更
冪等でない処理が多い 二重実行リスク リトライ抑制+冪等性設計が先

恒久対策の基本は「速く返す」か「待たせない設計」

恒久対策は、タイムアウトを“伸ばす”ではなく、タイムアウトが問題になりにくい構造に寄せるのが本質です。

  • 速く返す(性能改善)

    • DB:インデックス最適化、クエリ改善、ロック競合の解消、接続プールの見直し

    • アプリ:CPU/IOのボトルネック解消、スレッドプール調整、N+1の解消

    • 外部API:キャッシュ、並列化、サーキットブレーカー

  • 待たせない(設計変更)

    • 長時間処理は非同期化(ジョブ投入→受付応答→結果取得)

    • 処理を分割(ページング、段階的計算、バッチ化)

    • 失敗しても影響を小さく(フォールバック、縮退運転)

観測の型(再発防止のためのテンプレ)

再発防止で効くのは「次回の調査を速くする」ことです。以下は最低限揃える観測の型です。

ログ(相関のため)

  • 入口(LB/Ingress/Proxy)にrequest-idを付与し、下流へ伝播

  • アプリログにもrequest-idを出す

  • 可能ならDBクエリログにも関連ID(難しければ時刻相関で代替)

メトリクス(兆候のため)

  • p50/p95/p99レイテンシ(入口とアプリ双方)

  • 5xx率(504/502/503の内訳)

  • 同時接続数、ワーカー使用率、キュー長

  • 依存先のレイテンシとエラー率(DB/外部API)

トレース(根本原因のため)

  • スパンで「どこで待ったか」を可視化(DB、外部API、ロック待ちなど)

この“型”があると、次回は「ログがないから分からない」という状態を避けられます。


upstream request timeoutのよくある質問

どの値をどれだけ伸ばせばよいですか

まず、対象ルートの実測(p95/p99)を見てください。例えばp99が12秒で、既定タイムアウトが10秒なら、切れて当然です。
ただし、延長は「待ちが増えても破綻しない」ことが前提です。ワーカーや接続が張り付いている状態では、延長は障害を拡大させます。
Envoyではroute timeoutが「下流リクエストを受け取り終えてから」始まる点も踏まえ、アップロードと処理遅延を混同しないようにしてください。

特定の経路だけ起きるのはなぜですか

特定経路だけなら、原因はかなり絞れます。

  • その経路だけDBが重い(スロークエリ、ロック)

  • その経路だけ外部API依存がある

  • その経路だけレスポンスが大きい/計算が重い

  • その経路だけ別クラスタ/別リージョンへルーティングしている

  • その経路だけメッシュ設定(timeout/retry)が異なる

まず「他の経路と何が違うか」を表にし、差分から当たりを付けるのが最短です。

504が出てもバックエンドは処理を続けますか

状況によります。中継がタイムアウトしても、バックエンド側でキャンセルが伝播しない場合、処理が継続することがあります。
このとき、クライアントが再試行すると二重実行になり得ます。特に冪等でない処理(課金、注文確定、在庫引当など)は要注意です。恒久対策として、冪等性キー、重複排除、ジョブ化などを検討してください。

GKE internal Ingressで「upstream request timeout」が出たらアプリが原因ですか

アプリが遅いケースもありますが、まずは「その経路がEnvoyで中継される」ことを前提に観測点を合わせる方が近道です。GKEの公式ドキュメントでは、internal Application Load Balancer宛トラフィックがEnvoyでプロキシされるためこのエラーが出る場合がある、と説明されています。
したがって、アプリログだけを見て「何も出ていない」と困るより、LB/Ingress/中継側ログを先に確認してください。

Nginxのproxy_read_timeoutを伸ばしたら直りました。これで終わりですか

短期的には止血になりますが、根本が解決したとは限りません。上流処理が遅いままだと、待ちが増え、別の障害(ワーカー枯渇、接続枯渇、キュー増大)が出る可能性があります。
「なぜ遅いのか」をAPM/スローログで掴み、処理を短くするか、待たせない設計へ寄せるのが安全です。Nginxのタイムアウトは公式ドキュメントの通り“何を待つか”が分かれているため、connectとreadを混同しないで観測してください。


参考にした情報源