ELB の 504 エラー:原因と解決策

冒頭まとめ ELB の 504 Gateway Timeout を調べるとき、最初にやるべきことは原因の推測ではありません。その 504 を、ロードバランサが作ったのか、ターゲットが返したのかを確定させることです。 この2つは、調べる場所がまったく違います。前者ならロードバランサとターゲットの間の話、後者ならターゲットの内側の話です。にもかかわらず、クライアントから見える応答は同じ 504 です。 判定は一瞬で終わります。アクセスログの target_status_code を見るだけです。公式文書によれば、この欄はターゲットへの接続が確立され、かつターゲットが応答を返した場合にのみ記録され、それ以外は - になります。つまり elb_status_code が 504 で target_status_code が - ならロードバランサ生成、両方 504 ならターゲット自身が返した 504 です。多段構成でターゲット側に別の中継役がいる場合、後者になります。 ロードバランサ生成だった場合、原因は公式に6つ挙げられています。関わるタイマーは2種類で、接続を確立するまでの10秒と、応答を待つ idle timeout(既定60秒)です。前者は変更できません。 なお、よく混同されますが、ターゲット側の keep-alive がロードバランサの idle timeout より短い場合に返るのは 504 ではなく 502 です。公式の 502 の説明にその条件が明記されています。 エラーの概要 アクセスログの1行から読み取れる情報が、このエラーの診断の中心です。 https 2026-08-03T12:00:00.000000Z app/my-alb/50dc6c495c0c9188 203.0.113.10:54321 10.0.1.23:8080 0.001 -1 -1 504 - 512 0 "GET https://example.com:443/report HTTP/1.1" 読むべき欄は3つです。 elb_status_code が 504。target_status_code が -。この2つが揃えば、ロードバランサが生成した 504 です。 ...

2026年8月3日 · ErrorLog

Azure の 504 エラー:原因と解決策

冒頭まとめ Azure で 504 Gateway Timeout を受け取ったとき、出どころは2系統に分かれます。資源の作成や設定変更を受け付ける管理側の窓口が返すものと、利用者からの通信を取り次ぐ中継役が返すものです。前者は Azure Resource Manager、後者は Application Gateway や Azure Front Door などが該当します。 管理側の 504 には、原因を絞り込める特徴があります。文言に、応答しなかったリソースプロバイダの名前が含まれるためです。The gateway did not receive a response from 'Microsoft.Web' within the specified time period. のような形で、Microsoft.Web や Microsoft.App といった名前が入ります。この名前は、どの機能群が応答しなかったかを示します。自分が操作している資源の種類と一致していれば、その資源の担当が遅れています。一致していなければ、内部で呼ばれている別の機能群が遅れています。 最も注意すべき点は2つあります。1つ目は、504 を受け取っても操作が完了している場合があることです。管理側の窓口は要求を受け取って担当へ渡しており、担当の処理は続いています。応答が返る前に取り次ぎ役が待つのをやめただけ、という状況が実際に起きます。 2つ目は、Azure のソフトウェア開発キットの既定の挙動です。共通部分のソースを読むと、再試行の対象となる状態コードは 408・429・500・502・503・504 と定義されています。そのうえで、通常は再送しない POST と PATCH についても、500・503・504 のときだけは再試行する、という例外が明示的に書かれています。つまり、資源を作る要求が 504 で戻った場合、利用者が何もしなくても同じ要求がもう一度送られる可能性があります。 エラーの概要 管理側から返る場合、応答にはコード名と、リソースプロバイダ名を含む文言が入ります。 { "error": { "code": "GatewayTimeout", "message": "The gateway did not receive a response from 'Microsoft.App' within the specified time period." } } 各社の道具を経由している場合も、この文言はそのまま持ち回されます。たとえば構成管理の道具からは、次のような形で表示されます。 ...

2026年7月28日 · ErrorLog

GCP の 504 エラー:原因と解決策

冒頭まとめ GCP で 504 Gateway Timeout を受け取ったとき、出どころは大きく2つに分かれます。1つは各サービスの窓口(API)が返すもので、内部的には DEADLINE_EXCEEDED という区分に対応します。もう1つは Cloud Load Balancing が返すもので、こちらは背後の処理が時間内に応答しなかった場合に発生します。両者は調べる場所も直し方も違うため、最初に切り分ける必要があります。 窓口が返す 504 については、公式の定義そのものに重要な記述があります。GCP のエラー区分を定めた定義ファイルには、DEADLINE_EXCEEDED の説明として「状態を変更する操作の場合、操作が正常に完了していてもこのエラーが返ることがある」と書かれています。理由も添えられており、成功の応答が遅れて届いた結果、締め切りのほうが先に過ぎた場合がある、とされています。対応する HTTP の状態コードが 504 であることも同じ場所に記載されています。 つまり、作成や更新の操作で 504 を受け取ったとき、それは「失敗した」という通知ではありません。「結果が分からない」という通知です。そのまま再実行すると、二重に作ってしまう恐れがあります。 Cloud Load Balancing が返す 504 については、判別の手がかりがログにあります。statusDetails という項目が response_sent_by_backend であれば、ロードバランサは背後の応答をそのまま渡しただけです。それ以外の値であれば、ロードバランサ自身が作った応答です。公式のトラブルシューティング文書に、この見分け方が明記されています。 なお、種類によって挙動が違う点にも注意が要ります。公式文書によれば、グローバルおよびリージョンの外部アプリケーション ロードバランサは 503 や 504 といった意味のある状態コードを生成しますが、従来型のアプリケーション ロードバランサは常に 502 を使います。従来型を使っている環境では、待ち時間の超過も 502 として現れます。 エラーの概要 窓口が返す場合、応答には区分の名前が含まれます。 { "error": { "code": 504, "message": "Deadline exceeded", "status": "DEADLINE_EXCEEDED" } } 各社の道具やソフトウェアから呼んでいる場合、この区分名がそのままエラー文に現れることが多く、DEADLINE_EXCEEDED の文字列が手がかりになります。 ロードバランサが返す場合、応答は簡素なもので、詳細はログ側にあります。 { "httpRequest": { "status": 504 }, "jsonPayload": { "@type": "type.googleapis.com/google.cloud.loadbalancing.type.LoadBalancerLogEntry", "statusDetails": "backend_timeout" }, "resource": { "type": "http_load_balancer" } } backend_timeout は、公式文書に「背後の応答に時間がかかりすぎた」と説明されており、対処としてバックエンド サービスの待ち時間の設定を見直すか、なぜ応答に時間がかかっているかを調べることが挙げられています。 ...

2026年7月28日 · ErrorLog

Kubernetes の 504 エラー:原因と解決策

冒頭まとめ Kubernetes で 504 Gateway Timeout に出会う場面は、大きく2つに分かれます。API サーバーが自分の締め切りに達して要求を打ち切った場合と、Ingress などの中継役が背後の応答を待ちきれずに返した場合です。前者はクラスタの操作そのものが止まり、後者は利用者向けの通信が止まります。原因も対処もまったく別です。 API サーバーが打ち切った場合、文言は一意に定まっています。ソースを読むと、時間切れの応答は Timeout: request did not complete within the allotted timeout という文言で、区分は Timeout、状態コードは 504 として組み立てられます。kubectl からは Error from server (Timeout): の形で表示されます。この文言が出ていれば、打ち切ったのは API サーバー自身です。 締め切りの既定値は60秒です。API サーバーの起動時の指定として定義されており、変更にはクラスタ側の設定変更が要ります。 ここで重要なのが、クライアント側の指定との関係です。要求に待ち時間を付けて送ることはできますが、ソースの処理を読むと、指定された値が0より大きく、かつサーバー側の上限より小さい場合にだけ採用される、と書かれています。つまり、クライアント側で長い値を指定しても、サーバー側の締め切りは伸びません。短くすることはできても、伸ばすことはできない、という一方通行です。「待ち時間を伸ばす」という定番の対処が効かない理由がここにあります。 なお、監視や実行、ログの追従といった長時間動き続ける種類の要求は、この打ち切りの対象から外れます。ソースでも、該当する要求はそのまま通す分岐になっています。 エラーの概要 kubectl からは次の形で見えます。 Error from server (Timeout): error when creating "example.yaml": Timeout: request did not complete within the allotted timeout 応答そのものは次の構造です。区分と状態コードが対応しています。 { "kind": "Status", "status": "Failure", "message": "Timeout: request did not complete within the allotted timeout", "reason": "Timeout", "code": 504 } API サーバー側の記録には、要求ごとの処理時間と結果が残ります。時間切れになった要求は、要した時間とともに記録されます。 "HTTP" verb="GET" URI="/api/v1/namespaces/example/endpoints/sample?timeout=10s" latency="15.79s" resp=504 この例では、要求に10秒の指定が付いているにもかかわらず、15.79秒かかっています。指定した値と実際の処理時間は一致しません。 ...

2026年7月28日 · ErrorLog

Terraform の 504 エラー:原因と解決策

冒頭まとめ 504 Gateway Timeout は、要求を取り次いだ中継役が、その先からの応答を待ちきれずに返すエラーです。Terraform で目にする場合、出どころは3つに分かれます。本体がレジストリや配布元へ問い合わせたとき、プロバイダがクラウドの窓口へ要求したとき、そして経路上のプロキシや振り分け装置が返したときです。どの段階で出たかによって、調整できる場所も、調整すべき値も変わります。 先に押さえるべき性質が1つあります。504 は「失敗した」という通知ではありません。「待っていた側が待つのをやめた」という通知です。要求を受け取った先が処理を続けている可能性は残ります。作成の操作でこれを受けると、クラウド側には資源が出来上がっているのに Terraform は失敗として扱う、という食い違いが起きます。したがって、504 を受けたあとに最初にやるべきは再実行ではなく、実際に出来ているかどうかの確認です。 再試行の作法も段階ごとに違います。本体がレジストリへ問い合わせる部分は、既定で1回しか再試行しません。合計2回で諦める設計で、失敗時の文言に「2回試した」と出るのはこのためです。この回数は環境変数で増やせます。一方、プロバイダがクラウドの窓口を叩く部分は、各社の実装に従います。たとえば AWS の実装では 500・502・503・504 が再試行の対象と定義され、既定の試行回数は3回です。AWS のプロバイダはこれを25回まで引き上げています。 もう1つ、待ち時間の作法にも癖があります。共通して使われている再試行の仕組みでは、待ち時間は1秒から始めて倍々に増え、上限は30秒です。応答に含まれる待機の指示は 429 と 503 のときだけ読み取られ、504 では読み取られません。 エラーの概要 段階ごとに出方が違います。まず、terraform init の段階でレジストリや配布元から返る場合です。 Error: Failed to install provider Error while installing example/example v1.2.3: unsuccessful request to https://releases.example.com/terraform-provider-example_1.2.3_linux_amd64.zip: 504 Gateway Timeout レジストリへの問い合わせ自体が繰り返し失敗した場合は、再試行の回数を含む形になります。 Error: Failed to query available provider packages Could not retrieve the list of available versions for provider example/example: the request failed after 2 attempts, please try again later: 504 Gateway Timeout returned from https://registry.terraform.io/v1/providers/... この「2回試した」という数字は、既定の再試行回数が1回であることに対応しています。ソースでは、この文言を組み立てる処理が再試行の上限に達したときに呼ばれ、試行回数を添えるようになっています。 ...

2026年7月28日 · ErrorLog

Nginx の 504 エラー:原因と解決策

冒頭まとめ Nginx の 504 Gateway Time-out は、リバースプロキシとして上流(proxy_pass や fastcgi_pass の先)の応答を待ったが、時間内に届かなかったことを示します。時間切れになるタイマーは2つあり、どちらかはエラーログの文言で判別できます。文言が while connecting to upstream で終わっていれば、接続の確立自体が時間切れです(proxy_connect_timeout。原因は経路の問題が典型)。while reading response header from upstream で終わっていれば、接続はできたが応答が返らない時間切れです(proxy_read_timeout。原因は上流の処理の遅さが典型)。 対処の本筋は、時間を延ばすことではなく、どのタイマーがなぜ切れたかを特定することです。応答待ちの時間切れなら遅い処理の改善が本筋で、正当に時間のかかる処理に限ってタイムアウトを延ばします。その際、設定したのに効かないという定番の落とし穴(別の location が処理している、リロード漏れ)があるため、実効設定の確認までを対処に含めます。 エラーの概要 Nginx が自身の既定ページで504を返す場合、ブラウザには「504 Gateway Time-out」(Time-out はハイフン入り)という見出しだけが表示されます。エラーログには次のように記録されます。 2026/07/14 14:32:10 [error] 1234#1234: *567 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 192.168.1.100, server: example.com, request: "GET /api/report HTTP/1.1", upstream: "http://127.0.0.1:8080/api/report" 関係するタイマーの正確な仕様を押さえておくと、対処を誤りません。公式ドキュメントによると、proxy_connect_timeout(既定60秒)は上流との接続確立に対する制限で、通常75秒を超える値には設定できません。proxy_read_timeout(既定60秒)は応答の読み取りに対する制限ですが、応答全体の転送時間の上限ではなく、連続する2つの読み取り操作の間隔に適用されます。つまり上流が少しずつでもデータを送り続けていれば、全体が60秒を超えても切れません。切れるのは「この時間、何も送られてこなかった」ときです。proxy_send_timeout(既定60秒)は同様に、上流への書き込み操作の間隔に適用されます。PHP-FPM などの FastCGI 構成では、対応する fastcgi_read_timeout などが同じ意味を持ちます。 なお、似た状況で別のコードになる場合があります。上流への接続が即座に拒否された場合(プロセス停止・ポート違い)は504ではなく502です。また、Nginx が待っている間にクライアント側が先に諦めて切断した場合は、誰にも何も返らず、アクセスログに499が記録されます。 まず最初に:エラーログの文言でタイマーを特定する sudo grep "upstream timed out" /var/log/nginx/error.log | tail -10 該当行の末尾近くの文言を読みます。while connecting to upstream なら接続確立の時間切れで、調べるのは経路です(原因2)。while reading response header from upstream なら応答待ちの時間切れで、調べるのは上流の処理時間です(原因1)。 ...

2026年5月27日 · ErrorLog

AWS の 504 エラー:原因と解決策

冒頭まとめ AWS の 504 Gateway Timeout は、リクエストを中継するコンポーネントが、その先からの応答を待ちきれずに打ち切ったことを示します。対処を決めるのは「どの中継役の、どのタイマーで時間切れになったか」です。代表的な発生源は3つです。第一に Application Load Balancer(ALB)で、ターゲットへの接続確立が10秒の接続タイムアウト内に完了しない場合(経路の遮断が典型)と、接続後の応答が idle timeout(既定60秒)内に返らない場合(遅い処理が典型)があります。第二に Classic Load Balancer で、応答が idle timeout を超える場合と、バックエンドの keep-alive が先に切れて接続が閉じられる場合です。第三に API Gateway で、統合タイムアウト(既定29秒)内にバックエンドが応答しない場合に、Endpoint request timed out という504が返ります。 504 は「待った末の時間切れ」であり、接続自体の失敗や不正な応答(502)、ターゲットの未登録(503)とは原因の場所が異なります。まずどのタイマーかを特定し、遅い側を速くするか、待つ側の設定を実態に合わせるかを判断します。 エラーの概要 504 を最初に受け取ったとき、502 との違いを押さえておくと迷いません。502 は「相手から不正な応答を受け取った、または接続に失敗した」、504 は「応答を待ったが時間内に届かなかった」です。同じ「バックエンドの問題」でも、502 は接続や応答の形式、504 は時間が争点になります。 ALB では、504 の記録の形に特徴があります。実際の調査記録に共通するのは、アクセスログで elb_status_code が 504、target_processing_time と response_processing_time が -1、target_status_code が -(空)という形です。これは、ALB がターゲットからの応答を一度も受け取れないままタイムアウトで接続を閉じたことを意味します。API Gateway の場合は、応答本文そのものが手がかりです。 { "message": "Endpoint request timed out" } まず最初に:どのタイマーで時間切れになったかを特定する 発生源ごとに、見るべき記録が決まっています。 ALB 経由なら、CloudWatch の HTTPCode_ELB_504_Count(ALB が生成した504)を確認し、あわせて TargetConnectionErrorCount(接続確立の失敗)と TargetResponseTime(ターゲットの応答時間)を見ます。接続エラーが増えていれば経路の問題(原因1の接続確立側)、応答時間が idle timeout に張り付いていれば処理の遅さ(原因1の応答待ち側)です。 ...

2026年5月24日 · ErrorLog

Docker の 504 エラー:原因と解決策

冒頭まとめ Docker まわりの 504 Gateway Timeout で最初に確定させるべき事実は、Docker デーモン自身は504を返さない、ということです。デーモンがエラーを HTTP のステータスに割り当てる実装(moby のソースコード)には504がそもそも存在せず、時間切れ系の内部エラー(deadline exceeded)ですら500に割り当てられています。したがって、Docker の操作で504を見たとき、それを返しているのは必ずデーモン以外のどこかの「中継役」です。実際に起きる場所は3つに絞れます。第一に、docker pull / push の通信経路にあるゲートウェイ(自前レジストリの前段の Nginx や ingress、Docker Hub 側の基盤)です。第二に、リモートの Docker デーモンをリバースプロキシ越しに公開している構成の、そのプロキシです。第三に、コンテナで動かしているアプリケーションの前段のプロキシで、これは Docker ではなくプロキシとアプリの調査になります。 見分けは文言でつきます。received unexpected HTTP status: 504 Gateway Time-out や error parsing HTTP 504 response body なら、pull / push の経路の504です(原因1)。docker コマンド全般がリモートデーモン相手に504になるなら、デーモンの前のプロキシです(原因2)。ブラウザや curl でコンテナ上のアプリにアクセスして504が返るなら、それは Docker の問題ではありません(原因3として境界を示します)。 エラーの概要 Docker デーモンは、エラーの種類ごとに返す HTTP ステータスを割り当てます。この割り当てはソースコード(moby の daemon/server/httpstatus/status.go)で確認でき、404・400・409・503・500 などへの割り当てはあっても、504への割り当ては存在しません。つまり Error response from daemon: で始まるエラーの中に504の数字が現れた場合も、その504はデーモンが作ったものではなく、デーモンがレジストリなどの通信相手から受け取ったものの転記です。 pull / push で504を受け取ったときの文言は、レジストリクライアントの実装(docker/distribution の registry/client/errors.go)で決まっており、2種類あります。 Error response from daemon: received unexpected HTTP status: 504 Gateway Time-out Error response from daemon: error parsing HTTP 504 response body: invalid character '<' looking for beginning of value: "<html>\r\n<head><title>504 Gateway Time-out</title></head>\r\n..." 前者は、レジストリ API として想定外のステータスを受け取ったことを示します。後者はさらに手がかりが濃く、応答の本文がレジストリの返す JSON ではなく HTML だったことを示します。レジストリ本体は HTML のエラーページを返さないため、この文言は「応答したのはレジストリではなく、その手前にいる何か(Nginx やロードバランサー)だ」という強い証拠になります。 ...

2026年1月1日 · ErrorLog

GitHub API の 504 エラー:原因と解決策

冒頭まとめ GitHub API の 504 Gateway Timeout は、GitHub が制限時間内に応答を作り終えられず、リクエストを処理の途中で打ち切ったことを示すコードです。これは公式に明文化された挙動で、GitHub の公式文書(Troubleshooting the REST API)は、処理が10秒を超えるリクエストを打ち切ってタイムアウトの応答と Server Error のメッセージを返すこと、そしてこの制限時間は API の速度と信頼性を守るために予告なく変更されうることを明記しています。原因は2系統に整理できます。第一に、GitHub 側の障害や混雑で、普段は通るリクエストが散発的に時間切れになるケースです。第二に、リクエスト自体が重すぎて、平常時でも制限時間に収まらないケースです。 対処もこの公式文書がそのまま示しています。稼働状況を確認すること、要求を簡素化すること(1ページに100件を要求しているなら件数を減らす)、時間をおいて再試行することの3つです。逆に、トークンの不備は 401、レート制限は 403 または 429、不存在や権限不足は 404 として返るのが GitHub の仕様であり、これらが504の原因になることはありません。また、手元の HTTP クライアントに設定したタイムアウトの発火は、GitHub からコードが返る前に手元で接続を打ち切る動きなので、504とは別の事象です。504の調査は、コードが本当に GitHub から返っているかの確認と、「散発か、重さ由来か」の見極めから始めます。 エラーの概要 GitHub は API リクエストの処理時間に上限を設けており、超過したリクエストを自らの判断で打ち切ります。打ち切られたリクエストへの応答は次のような形になります。 $ curl -i -H "Authorization: Bearer <your-github-token>" \ "https://api.github.com/repos/<owner>/<repo>/commits?per_page=100" HTTP/2 504 ... { "message": "Server Error", "documentation_url": "https://docs.github.com/rest" } この Server Error という文言は、公式文書がタイムアウト応答に伴うと明記しているメッセージです。なお、同じ「時間内に応答を作れなかった」状態は、経路や API の種類によって 502 として現れることもあります。特に GraphQL API の重いクエリの時間切れは、参照 ID 入りのエラーメッセージを伴う 502 の形の報告が多く、その扱いは GitHub API の 502 の記事で説明しています。コードが502でも504でも、時間切れである限り、原因の見極め方と対処(縮小・分割・再試行)は共通です。 まず最初に:3点を確認する 504を受け取ったら、コードを変更する前に次の3点を確認します。 第一に、そのコードが本当に GitHub から返っているかを確認します。手元のクライアントのタイムアウト(curl の –max-time、requests の timeout= など)が先に発火した場合、ステータスコードは受け取れず、例外や接続打ち切りとして現れます。この場合の調査対象は GitHub ではなく、手元の設定と経路です。 第二に、GitHub の稼働状況ページ(https://www.githubstatus.com)を確認します。公式文書も、時間切れが API 側の問題によるものかをこのページで確認するよう案内しています。インシデントが進行中なら原因は自分のリクエストではありません(原因1)。掲載が遅れることもあるため、掲載がないことは障害でないことの証明にはなりません。 ...

2026年1月1日 · ErrorLog