UnsplashのMarkus Spiskeが撮影した写真
Webサイトが突然「Internal Server Error」と表示され、ページが開けなくなる――その代表例がHTTPステータスコードの500(Internal Server Error)です。500は「サーバー側で想定外の状態が起き、リクエストを完了できなかった」ことを示す汎用的なエラーで、画面だけでは原因が分かりません。この記事では、500の意味を押さえた上で、起きやすい原因、調査・対処の手順、再発防止の実務ポイントまでをまとめて解説します。
500(Internal Server Error)は、HTTPステータスコードの一種であり、サーバーが予期しない状況に遭遇し、リクエストを完了できなかったことを示します。より具体的には、アプリケーションの未処理例外、設定不備、依存先(DBや外部APIなど)の失敗、リソース枯渇といった要因で、サーバーが正常なレスポンス(HTMLやJSONなど)を返せなかったときに返される「汎用(catch-all)」のエラーです。
重要なのは、500自体は「サーバー側で失敗した」という結果を示すだけで、原因を特定する情報を含まない点です。原因特定には、エラーログ、アプリケーションログ、監視指標(CPU・メモリ・ディスク・DB接続数など)、直前の変更(デプロイ・設定変更)といった周辺情報が不可欠になります。
HTTPステータスコードは、Webサーバーからクライアントに返す応答の状態を示す3桁の数字です。大きく以下の5つに分類され、500は「5xx(サーバーエラー)」に属します。
500は「サーバー側の処理失敗」を表す代表的なコードであり、適切に切り分けできないまま500を返し続けると、障害対応が遅れたり、利用者の不信感を招いたりします。運用では「どの層(Web/アプリ/依存先)で失敗しているか」を最短で判断できる情報設計が重要です。
500エラーは「サーバー内部で何かが失敗した」状態の総称なので、原因は多岐にわたります。実務でよく遭遇する代表例をカテゴリ別に整理すると次のとおりです。
原因特定では「いつから」「どのURL/機能で」「どのユーザー/条件で」「直前に何が変わったか」をセットで確認すると、ログを読む範囲が一気に狭まり、手戻りが減ります。
500は汎用コードですが、実務では状況に応じて別のステータスコードの方が切り分けしやすい場合があります。違いを押さえると、調査と復旧が速くなります。
| エラーコード | 主な意味 | 実務での見立て |
|---|---|---|
| 400 Bad Request | リクエストが不正 | 入力・形式・JSON不正など(本来はサーバーで弾く領域) |
| 401 Unauthorized | 認証が必要 | ログイン・トークン不備、認証フローの問題 |
| 403 Forbidden | アクセス拒否 | 権限・WAF・IP制限・ACLなど |
| 404 Not Found | リソースが存在しない | URL誤り、ルーティング不備、公開漏れ |
| 500 Internal Server Error | サーバー内部の想定外の失敗 | アプリ例外、設定不備、依存先処理失敗のハンドリング不備など |
| 501 Not Implemented | 機能が未実装 | 要求メソッド/機能をサーバーが実装していない(構成・設定不足を含む) |
| 502 Bad Gateway | ゲートウェイ/プロキシが上流から不正な応答を受けた | リバプロ/LB配下の上流障害・設定不整合・上流が落ちている |
| 503 Service Unavailable | 一時的に利用不可 | メンテナンス、過負荷、起動中、意図的に落としている状態 |
| 504 Gateway Timeout | ゲートウェイ/プロキシが上流の応答待ちでタイムアウト | DBや外部API遅延、上流処理の停滞、タイムアウト値不適切 |
運用上は「本当は502/504に寄せた方が早いのに、アプリが握りつぶして500になっている」ケースもあります。切り分けしやすいステータス設計は、再発防止にも直結します。
500エラー対応のゴールは「いま復旧させる(一次対応)」と「原因を潰して再発を防ぐ(二次対応)」を分けて達成することです。ここでは、現場で迷いにくい順番で進め方を整理します。
ここが曖昧だと、ログを見ても候補が広がりすぎます。まずは「再現できる条件」を短時間で作ることが、復旧までの最短ルートです。可能なら、発生時刻・対象URL・ユーザー条件をメモとして残し、以後の調査の基準点にします。
次に、Webサーバー(Apache/Nginx)やリバースプロキシ、ロードバランサのログを確認します。ログには、時刻、対象URL、ステータス、上流への転送先、タイムアウトや接続エラーなどの手がかりが残ります。
運用で効果が大きいのは、入口でリクエストIDを付与し、全ログに出すことです。たとえば X-Request-ID をLB/リバプロで付与し、Webログにもアプリログにも同じIDを出すと、Web→アプリ→DB→外部APIまで追跡が一気に楽になります。
500の直接原因は、アプリ側の未処理例外であることが少なくありません。アプリケーションログを見て、例外メッセージとスタックトレース(どの処理で落ちたか)を確認します。
ここで見るべきポイントは「どの入力・どの条件で落ちたか」です。例外種別だけでなく、可能な範囲で入力の要点(個人情報は避け、サイズや種別など)がログに残る設計にしておくと、再現と修正が速くなります。
Webとアプリに明確な手がかりがない場合、依存先の遅延・障害・枯渇を疑います。依存先が失敗したときにアプリが適切にハンドリングできない(タイムアウト処理不足、例外処理不足)と、結果として500になりやすい点にも注意が必要です。
特に「特定ページだけ500」「アクセス増のタイミングで500」が重なる場合は、DBや外部APIの遅延がトリガーになっていることが多いです。まずはタイムアウト・接続数・待ち行列(ワーカー枯渇)が増えていないかを確認します。
原因究明に時間がかかるときは、サービス継続を優先して一次対応を行います。代表的な手段は次のとおりです。
一次復旧の目的は「ユーザー影響を止血すること」です。復旧後は、必ず二次対応(恒久対策)に進みます。一次対応の内容と判断理由を簡潔に記録しておくと、振り返りと再発防止が進めやすくなります。
500の再発防止は、コード品質だけでなく「運用設計」とセットで考えるのが現実的です。ここでは、効果が出やすい順に整理します。
例外を握りつぶさず、適切に捕捉してログに残すことが基本です。ユーザー向けには過度に詳細を出さず、運用側には原因追跡できる情報(例外種別、スタック、リクエストID、処理名、依存先の状態)を記録します。とくに「同じ例外が急増した」ことを検知できる形にすると、初動が速くなります。
不正入力は本来4xxで返すべき領域です。バリデーションを徹底し、「入力が悪いのか」「サーバー内部が悪いのか」をレスポンスで分けると、500の濫発を防げます。また外部APIやDBの失敗は、可能なら502/503/504など適切なコードに寄せ、運用で切り分けしやすくします(アプリ側で“依存先の失敗”を明確に扱う設計がポイントです)。
500は「起きた後」に気づくのが一番痛いタイプの障害です。最低限、次の観測点を揃えると、調査の入口が定まります。
運用では「どこで詰まったか」を早く判断することが重要です。監視指標は“きれいな平均”よりも、p95/p99やキューの増大など、詰まりを示す指標を優先します。
高負荷時に何が先に壊れるかを事前に把握しておくと、500の大量発生を避けられます。負荷テストでは、ピーク時の同時接続、DB接続上限、ワーカー枯渇、タイムアウト設定の妥当性、キャッシュの効果(逆にキャッシュ障害時の挙動)などを確認します。
OS、Webサーバー、ランタイム、フレームワーク、ライブラリの更新は、脆弱性対策だけでなく安定性の観点でも重要です。あわせて、段階的デプロイ(カナリア等)、ロールバック手順、マイグレーションの互換性確保(前方互換)を整えると、リリース起因の500を減らせます。
500が出たとき、ユーザーは「自分が悪いのか」「待てば直るのか」が分かりません。エラーページには、謝意、再試行の案内、障害告知ページへの導線、問い合わせ窓口、発生時刻や問い合わせ用の識別子(リクエストIDなど)を表示すると混乱が減ります。表示内容は最小限にしつつ、運用側が追える情報を確保するのがポイントです。
根本原因はサーバー側にあるため、ユーザー操作だけでの恒久解決はできません。
500は想定外の内部エラー、503はメンテナンスや過負荷などで一時的に提供できない状態です。
そのページ固有の処理(テンプレート、DBクエリ、プラグイン、外部API呼び出し)の例外やタイムアウトを疑います。
まずWebサーバー/リバプロのエラーログ、次にアプリケーションログの例外スタックを確認します。
直前リリースのロールバック、問題機能の停止、スケールアウトなどで影響を止血します。
なります。依存先の失敗を適切に扱えないと、アプリ例外として500が返ることがあります。
はい。謝意と案内に加え、問い合わせ導線と時刻・リクエストIDなどの手がかりを用意すると混乱が減ります。
設定例はErrorDocument 500 /errors/500.htmlで、サーバー内のURLパスを指定して配置します。
設定例はerror_page 500 502 503 504 /50x.html;で、必要ならlocation = /50x.html { internal; }を併用します。
ログ・監視・トレーシングを整え、原因特定と復旧のスピードを上げることです。
500(Internal Server Error)は、サーバーが想定外の状態に遭遇してリクエストを完了できなかったことを示す汎用的なHTTPステータスコードです。原因はアプリ例外、設定不備、依存先の失敗、リソース枯渇、デプロイ起因など多岐にわたるため、影響範囲の切り分け→Web/リバプロログ確認→アプリ例外確認→依存先確認の順に調査すると効率的です。再発防止には、例外処理の整備に加え、ログ設計(リクエストID)、監視・トレーシング、安全なデプロイ手順、ユーザー向け案内の整備を組み合わせ、原因特定と復旧のスピードを上げることが重要です。