504 Gateway Timeoutとは?原因と解決方法を徹底解説

504 Gateway Timeoutとは?
504 Gateway Timeoutは、ゲートウェイまたはプロキシとして機能しているサーバーが、アップストリームサーバーから時間内にレスポンスを受信できなかったことを示すHTTPステータスコードです。プロキシはアップストリームのレスポンスを待っていましたが、時間がかかりすぎたため、プロキシは待機を中止してブラウザに504を返しました。
公式な定義はRFC 9110(HTTPセマンティクス)のセクション15.6.5に記載されています。「504(Gateway Timeout)ステータスコードは、サーバーがゲートウェイまたはプロキシとして動作中に、リクエストを完了するためにアクセスする必要があるアップストリームサーバーから時間内にレスポンスを受信できなかったことを示す。」
キーワードはゲートウェイです。504エラーには必ず2つ以上のサーバーが関与しています。接続先のサーバー(プロキシ/ゲートウェイ)と、その背後にあるレスポンスを返せなかったサーバー(アップストリーム/オリジン)です。一般的なプロキシには、Nginxリバースプロキシ、Cloudflare、AWS Application Load Balancer(ALB)、CloudFrontなどがあります。
504エラーの表示例
504エラーのメッセージは、ブラウザ、Webサーバー、CDNによって異なります。よく目にするメッセージの例を以下に示します。
504 Gateway Timeout
504 Gateway Time-out(Nginxのデフォルト — ハイフン付き)
HTTP Error 504 — Gateway Timeout
このページは動作していません — [ドメイン]からの応答に時間がかかりすぎています(Chrome / Edge)
Gateway Timeout(Firefox)
Error 504
504 Gateway Time-out — The server didn't respond in time(Apacheのmod_proxy使用時)
Error 524: A timeout occurred(Cloudflare独自 — 厳密には504ではないが、根本原因は同じ)
ERROR — The request could not be satisfied — 504 ERROR(AWS CloudFront)
表示されるメッセージの文言に関わらず、根本的な原因は常に同じです。プロキシサーバーがアップストリームサーバーのレスポンスを待っていたが、設定されたタイムアウト時間内にアップストリームサーバーがレスポンスを返さなかったということです。
504 Gateway Timeoutが発生する仕組み
504エラーを理解するには、ブラウザとオリジンサーバー間のタイムアウトチェーンを理解する必要があります。一般的なWebリクエストは複数のレイヤーを通過し、各レイヤーにはそれぞれ独自のタイムアウト設定があります。
一般的なリクエストフローは次のとおりです:ブラウザ → CDN(Cloudflare) → ロードバランサー → Nginx → PHP-FPM → データベース。データベースクエリに90秒かかり、Nginxのproxy_read_timeoutが60秒に設定されている場合、Nginxは待機を中止して504をロードバランサーに返し、それがブラウザに渡されます。
504を返すサーバーは常に中間サーバー(プロキシまたはゲートウェイ)であり、オリジンサーバー自体ではありません。オリジンサーバーは単に時間内にレスポンスを返さなかっただけで、まだリクエストを処理中かもしれませんし、完全にクラッシュしている可能性もあります。
| レイヤー | デフォルトのタイムアウト | タイムアウト時の動作 |
|---|---|---|
| Cloudflare(Free/Pro) | 100秒 | Error 524を返す(独自コード) |
| AWS CloudFront | 30秒 | 504 ERRORを返す |
| AWS ALB | 60秒 | awselbヘッダー付きの504を返す |
| GCP Load Balancer | 30秒 | 504を返す |
| Nginx(proxy_read_timeout) | 60秒 | 504 Gateway Time-outを返す |
| Apache(ProxyTimeout) | 60秒 | 504 Gateway Timeoutを返す |
| PHP max_execution_time | 30秒 | スクリプトが終了し、Nginxがレスポンスを受信できず504を返す |
504 Gateway Timeoutの一般的な原因
根本原因を理解することが、最速の解決への道です。サーバーが504を返す最も一般的な理由を、発生頻度順に紹介します。
遅いオリジンサーバー — 複雑なデータベースクエリの実行、レポート生成、低速なサードパーティAPIの呼び出しを行うPHPスクリプトが、プロキシのタイムアウトを超過する場合があります。これが504エラーの最も多い原因です。
サーバーの過負荷 — CPUが100%、メモリ不足(OOM kill)、すべてのPHP-FPMワーカーがビジー状態。オリジンサーバーは稼働しているが、レスポンスを返すのに時間がかかりすぎています。
データベースのボトルネック — 遅いSQLクエリ、インデックスの欠如、テーブルロック、コネクションプールの枯渇。アプリケーションがデータベース待ちでハングし、プロキシがタイムアウトします。
タイムアウト値の設定ミス — バックエンドが正当にもっと時間を必要とする場合(レポート生成やファイルアップロードなど)に、Nginxの
proxy_read_timeoutが低すぎる設定になっている。プロキシとオリジン間のネットワーク問題 — データセンター間のパケットロス、高レイテンシ、ルーティングの問題。マルチリージョンやハイブリッドクラウド環境でよく発生します。
ファイアウォールやセキュリティグループによるトラフィックブロック — AWSセキュリティグループがエフェメラルポートのトラフィックを許可していない、iptablesが内部接続をブロックしている、WAFが正当なアップストリームリクエストをブロックしている。
プロキシでのDNS解決の失敗 — プロキシがアップストリームのホスト名を解決できない。Nginxでは、
proxy_passで変数を使用しresolverディレクティブを設定していない場合に発生します。CDNのタイムアウト — CloudflareはFree/Pro/Businessプランで100秒の厳密な制限があります。オリジンが100秒以上かかる場合、Nginx設定に関わらずCloudflareはError 524を返します。
DDoS攻撃 — 大量のリクエストがサーバーリソースを消費し、プロキシのタイムアウト時間内に正規トラフィックへのレスポンスが遅くなります。
訪問者向けの対処法
他のウェブサイトで504エラーが表示された場合、問題はそのサーバー側にあり、あなたのデバイスの問題ではありません。ただし、いくつか試せることがあります。
待ってからページを更新する — ほとんどの504エラーは一時的です。30〜60秒待ってから、
Ctrl+Shift+R(Windows/Linux)またはCmd+Shift+R(Mac)でスーパーリロードしてください。全員に対してサイトがダウンしているか確認する — DNS RobotのHTTPヘッダーツールを使って、外部ロケーションからサーバーのレスポンスコードを確認しましょう。全員に504が返される場合、サーバー側の問題です。
シークレットモードまたは別のブラウザで試す — ブラウザ拡張機能、キャッシュされたエラーページ、ローカル設定の問題を排除できます。
別のネットワークで試す — Wi-Fiからモバイルデータに切り替えるか、VPNを無効にしてみてください。ISPとサーバー間のルーティング問題が504を引き起こすことがあります。
DNSキャッシュをフラッシュする — 古いDNSレコードがリクエストを間違ったサーバーにルーティングする場合があります。Windowsの場合:
ipconfig /flushdns。Macの場合:sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder。サイトのステータスページやSNSを確認する — 既知の障害やメンテナンス情報が公開されている場合があります。
対処法1:タイムアウト設定を引き上げる(Nginx & Apache)
504エラーの最も一般的な修正方法は、リバースプロキシのタイムアウト値を引き上げることです。バックエンドが正当にデフォルトの60秒以上を必要とする場合、プロキシにもっと長く待つように設定する必要があります。
# Nginx — reverse proxy to a backend (Node.js, Python, etc.)
location / {
proxy_pass http://backend;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;
}
# Nginx — FastCGI (PHP-FPM)
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_read_timeout 300;
fastcgi_send_timeout 300;
fastcgi_connect_timeout 300;
include fastcgi_params;
}Apacheでmod_proxyを使用している場合は、VirtualHostにProxyTimeout 300を追加するか、バックエンド個別の設定としてProxyPass / http://backend:8080/ timeout=300を使用してください。
重要:これらのタイムアウトは、2つの連続する読み取り/書き込み操作の間の時間を測定するもので、転送全体の時間ではありません。proxy_read_timeout 300は「300秒間データが到着しなければ」という意味であり、「レスポンス全体が300秒以内に完了しなければならない」という意味ではありません。タイムアウト値を変更した後は、設定をリロードしてください:sudo nginx -t && sudo systemctl reload nginx。
対処法2:遅いスクリプトとデータベースクエリを最適化する
バックエンドが常にタイムアウトを超過する場合、タイムアウト値を引き上げるだけでは問題を隠しているだけです。本当の修正はバックエンドのレスポンスを速くすることです。
遅いクエリを特定する — MySQLのスロークエリログを有効にし(
slow_query_log = 1、long_query_time = 1)、疑わしいクエリにEXPLAIN ANALYZEを使用してください。不足しているインデックスを追加し、SELECT *を避け、大きな結果セットをページネーションしてください。キャッシュを追加する — RedisやMemcachedを使用して、負荷の高いクエリ結果をキャッシュしましょう。毎回のページ読み込みで5秒かかるクエリはキャッシュすべきです。
重い処理をバックグラウンドジョブに移動する — レポート生成、メール送信、画像処理、データインポートはジョブキュー(Celery、Sidekiq、Bull)で実行し、HTTPリクエストサイクル内で行わないでください。
API呼び出しを最適化する — バックエンドが遅いサードパーティAPIを呼び出す場合、それらの呼び出しにタイムアウトを追加し、1つの遅いAPIがすべてのリクエストをブロックしないようサーキットブレーカーを実装してください。
N+1クエリを削減する — ORMが生成するクエリは数百の個別のデータベース呼び出しを行うことがあります。イーガーローディングやバッチクエリを使用してラウンドトリップを減らしてください。
対処法3:サーバーリソースを確認する(CPU、RAM、ディスク)
オリジンサーバーが過負荷の場合、リクエストを十分な速さで処理できず、プロキシが待ちきれずタイムアウトします。何がリソースを消費しているか確認しましょう。
# Check CPU and memory usage
top -bn1 | head -20
# Check disk space (full disk = silent failures)
df -h
# Check memory details
free -m
# Find processes using the most CPU
ps aux --sort=-%cpu | head -10
# Find processes using the most memory
ps aux --sort=-%mem | head -10
# Check active network connections
ss -sCPUまたはRAMが90%以上の場合、アプリケーションを最適化するか、暴走プロセスを停止するか、サーバーをアップグレードする必要があります。ディスク容量がいっぱいの場合は、古いログファイル、バックアップ、一時ファイルを削除してください。ディスク満杯はデータベースをサイレントにクラッシュさせ、連鎖的な504エラーを引き起こす可能性があります。
対処法4:エラーログを確認する
エラーログは、プロキシが504を返した正確な理由を教えてくれます。原因を推測する前に、必ずログを確認してください。
# Nginx error log (look for "upstream timed out")
tail -50 /var/log/nginx/error.log
# Apache error log
tail -50 /var/log/apache2/error.log # Debian/Ubuntu
tail -50 /var/log/httpd/error_log # CentOS/RHEL
# PHP-FPM log
tail -50 /var/log/php8.2-fpm.log
# System log (OOM kills, crashes)
tail -50 /var/log/syslog504を引き起こす一般的なログメッセージ:
"upstream timed out (110: Connection timed out)"(Nginx) — アップストリームサーバーがproxy_read_timeout内にレスポンスを返しませんでした。タイムアウトを引き上げるか、遅いアップストリームを修正してください。
"server reached pm.max_children"(PHP-FPM) — すべてのPHPワーカープロセスがビジーです。PHP-FPMプール設定でpm.max_childrenを引き上げてください。
"connect() failed (111: Connection refused)"(Nginx) — アップストリームサーバーが動作していないか、想定されるポートでリッスンしていません。バックエンドを再起動してください。
"Too many connections"(MySQL) — データベースの接続制限が枯渇しています。MySQL設定でmax_connectionsを引き上げるか、コネクションプーリングを最適化してください。
対処法5:PHP-FPMの設定を調整する
PHPベースのアプリケーション(WordPress、Laravel、Magento)では、PHP-FPMがボトルネックになることがよくあります。タイムアウトチェーンは一貫性を持たせる必要があります:Nginxのタイムアウト ≥ PHP-FPMのタイムアウト ≥ PHPのmax_execution_time。
| 設定項目 | ファイル | デフォルト | 推奨値 |
|---|---|---|---|
| max_execution_time | php.ini | 30秒 | 120〜300秒 |
| request_terminate_timeout | PHP-FPMプール設定 | 0(max_execution_timeを使用) | max_execution_timeに合わせる |
| pm.max_children | PHP-FPMプール設定 | 5 | RAMに基づく:(総RAM - 1GB) / 40MB |
| pm.max_requests | PHP-FPMプール設定 | 0(無制限) | 500〜1000(メモリリーク防止) |
| fastcgi_read_timeout | nginx.conf | 60秒 | ≥ max_execution_time |
PHP-FPMの設定を変更した後は、サービスを再起動してください:sudo systemctl restart php8.2-fpm。Nginxのfastcgi_read_timeoutは常にPHPのmax_execution_time以上に設定してください。そうしないと、PHPの処理が完了する前にNginxが待機を中止し、504が発生します。
対処法6:CDNとプロキシの設定を確認する
サイトがCloudflareやAWS CloudFrontなどのCDNの背後にある場合、CDNには独自のタイムアウト設定があり、サーバーの設定を上書きする可能性があります。
| CDN / プロキシ | デフォルトのタイムアウト | 最大設定可能値 | 備考 |
|---|---|---|---|
| Cloudflare Free | 100秒 | 100秒(固定) | 504ではなくError 524を返す |
| Cloudflare Pro | 100秒 | 100秒(固定) | Freeと同じ — 変更不可 |
| Cloudflare Business | 100秒 | 100秒(固定) | 同じ制限が適用 |
| Cloudflare Enterprise | 100秒 | 6,000秒 | Cache Rulesで設定可能 |
| AWS CloudFront | 30秒 | 180秒 | ディストリビューションのオリジン設定で設定 |
| AWS ALB | 60秒 | 設定可能 | アイドルタイムアウトで設定 |
| GCP Load Balancer | 30秒 | 実質制限なし | バックエンドサービスのタイムアウトで設定 |
Cloudflareユーザー:Free、Pro、Businessプランを使用しており、オリジンが100秒以上かかる場合、常にError 524が返されます。選択肢は、バックエンドを100秒以内にレスポンスするよう最適化するか、長時間の処理をバックグラウンドジョブに移行するか、Enterpriseにアップグレードすることです。
AWS CloudFrontユーザー:ディストリビューションのオリジン設定でオリジンレスポンスタイムアウトを引き上げてください。デフォルトの30秒は動的コンテンツには短すぎることが多いです。
DNS RobotのHTTPヘッダーツールを使用して、レスポンスヘッダーを確認し、どのレイヤーが504を返しているか特定してください。server: cloudflare、server: awselb/2.0、server: nginxなどのヘッダーでプロキシを特定できます。
対処法7:WordPress固有の解決策
WordPressサイトは、重いプラグイン、データベースの肥大化、共有ホスティングの制限により、504エラーが特に発生しやすいです。ここではWordPressに特化した修正方法を紹介します。
遅いプラグインを特定する — すべてのプラグインを無効化し、1つずつ再有効化してください。wp-adminにアクセスできない場合は、SSH経由で
pluginsフォルダをリネームしてください:mv wp-content/plugins wp-content/plugins_disabled。Query Monitorプラグインを使用して遅いデータベースクエリを特定しましょう。PHPメモリを増やす —
wp-config.phpにdefine('WP_MEMORY_LIMIT', '512M');を追加してください。多くのプラグインはデフォルトの128MB以上を必要とします。キャッシュプラグインをインストールする — WP Super Cache、W3 Total Cache、またはWP Rocketは、毎回のリクエストでPHPを実行する代わりに静的HTMLを配信することで、サーバー側の処理を削減します。
オブジェクトキャッシュを使用する — RedisまたはMemcachedとWordPressオブジェクトキャッシュプラグインをインストールしてください。これによりデータベースクエリ結果がメモリにキャッシュされ、MySQLの負荷が軽減されます。
データベースをクリーンアップする — 古い投稿リビジョン、トランジエント、スパムコメント、孤立したメタデータを削除してください。WP-OptimizeまたはWP-Sweepを使用しましょう。
wp-config.phpにdefine('WP_POST_REVISIONS', 5);を追加して、今後のリビジョン数を制限してください。wp-cronを無効化する — WordPressの仮想cronは毎回のページ読み込みで実行され、タスクが蓄積される可能性があります。
wp-config.phpにdefine('DISABLE_WP_CRON', true);を追加し、代わりにサーバーの実際のcronジョブを設定してください:*/5 * * * * curl -s https://yoursite.com/wp-cron.php > /dev/null 2>&1。
504 vs 502 vs 503 vs 408:それぞれの違い
これらのHTTPエラーコードはよく混同されます。それぞれの正確な意味を解説します。
| コード | 名前 | 何が起こったか | プロキシが必要? |
|---|---|---|---|
| 408 | Request Timeout | クライアントがサーバーへのリクエスト送信に時間がかかりすぎた | 不要 — サーバーがクライアントをタイムアウトさせる |
| 502 | Bad Gateway | プロキシがアップストリームから無効または不正なレスポンスを受信した | 必要 |
| 503 | Service Unavailable | サーバーが過負荷またはメンテナンス中で、リクエストを処理できない | 不要 — どのサーバーでも返せる |
| 504 | Gateway Timeout | プロキシがタイムアウト内にアップストリームからレスポンスを受信できなかった | 必要 |
| 524 | A Timeout Occurred | Cloudflareがオリジンに接続したが、100秒以内にHTTPレスポンスを受信できなかった | Cloudflareのみ(非標準) |
重要な違い:502はプロキシが不正なレスポンスを受け取ったことを意味し、504はプロキシがレスポンスをまったく受け取れなかったことを意味します。503はプロキシを必要とせず、過負荷時にどのサーバーでも返せます。408はクライアント側のタイムアウト(4xxクラス)で、サーバーがクライアントの送信を待ちきれなかった場合です。
502と504が同時に発生する場合、アップストリームサーバーがクラッシュしている可能性が高いです。502はプロキシが死にかけているプロセスから部分的または不正なレスポンスを受け取った場合に発生し、504はプロセスが完全に応答しなくなった場合に発生します。
504エラーはSEOに影響するか?
簡潔な回答:短時間の504はSEOに影響しません。長時間の504はインデックス削除につながる可能性があります。
数分〜数時間:影響なし。Googleは一時的なサーバーエラーを理解しており、即座にペナルティを課しません。障害中にGooglebotがクロールしなければ、気づくこともありません。
数時間〜数日:Googleは5xxエラーを返すサイトのクロール頻度を下げ、負荷を増やさないようにします。Google Search Consoleのページインデックスレポートで「サーバーエラー(5xx)」として表示される場合があります。
数日〜数週間:持続的な504エラーは、影響を受けたページのインデックス削除につながる可能性があります。ランキングが大幅に低下します。GoogleのJohn Mueller氏によると、サーバーが1日ダウンした場合、復旧後1〜3週間は状況が「不安定」になる可能性があります。
復旧:サーバーが安定すれば、Googleは自動的にページを再クロール・再インデックスします。Google Search ConsoleのURL検査ツールを使用して、重要なページの再インデックスをリクエストしてください。復旧時間はサイトの規模とエラーが続いた期間によって異なります。
504 Gateway Timeoutを予防する方法
予防は消火活動よりもはるかに効果的です。タイムアウト制限内でサーバーを安定して稼働させるためのベストプラクティスを紹介します。
監視を設定する — 稼働監視(UptimeRobot、Pingdom、またはDNS RobotのPingツール)を使用して、ユーザーから報告される前に504エラーを検知しましょう。
タイムアウトチェーンを一致させる — CDNのタイムアウト ≥ プロキシのタイムアウト ≥ アプリケーションのタイムアウトとなるようにしてください。不一致な値は予測不能な504エラーを引き起こします。
ヘルスチェックを実装する — ロードバランサーとプロキシはアップストリームサーバーをヘルスチェックし、応答しないインスタンスからトラフィックを迂回させるべきです。
積極的にキャッシュを活用する — 静的アセット、APIレスポンス、データベースクエリをキャッシュしてください。キャッシュされたレスポンスは504の原因になるほど遅くなることはありません。
オートスケールを導入する — 水平スケーリング(インスタンスの追加)を使用して、トラフィックの急増が単一サーバーを圧倒しないようにしましょう。
重い処理をオフロードする — ファイル処理、レポート生成、メール送信、一括インポートはバックグラウンドジョブキューに移行してください。HTTPリクエスト内で高負荷な処理を行わないでください。
遅いクエリを監視する — MySQL/PostgreSQLのスロークエリログを有効にしてください。1秒を超えるクエリに対してアラートを設定しましょう。
依存関係の健全性を保つ — バックエンドが依存するサードパーティAPIを監視してください。1つの遅いAPIがすべてのユーザーに504エラーを連鎖させないよう、タイムアウトとサーキットブレーカーを追加してください。
サーバーのレスポンスを確認する
DNS RobotのHTTPヘッダーツールを使って、サーバーのHTTPステータスコード、レスポンスヘッダー、タイミングを確認し、504エラーをデバッグしましょう。
Try HTTP Headers CheckerFrequently Asked Questions
504 Gateway Timeoutは、プロキシまたはゲートウェイサーバー(Nginx、Cloudflare、ロードバランサーなど)がアップストリーム/オリジンサーバーのレスポンスを待っていたが、アップストリームサーバーが時間内にレスポンスを返さなかったことを意味します。プロキシは待機を中止し、ブラウザに504エラーを返しました。