【AWS】ALBに4XX、5XXエラーコードのトラブルシューティングについて

# はじめに
AWSでALB→EC2への疎通がうまくできなかったら、よく4XXか5XXのエラーコードが返してきた経験があります。
4XX、5XXエラーコードは何を指しているか、またそのエラーコードが返してきた際に、
何を優先してトラブルシューティングするかをまとめていきたいです。

# 4XX、5XXエラーコード
結論から申し上げますと、
**4XXはクライアント側エラー**
**5XXはサーバー側エラー**
になります。

エラーコードの詳細内容は、下記のサイトをご覧いただければと思います。

https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

# HTTP 502: Bad gateway
Wikipediaから参考すると、502エラーコードの意味は以下となります。
>502 Bad Gateway
>The server was acting as a gateway or proxy and received an invalid response from the upstream server.[63]

502 Bad Gateway問題に遭いましたら、優先的にALBからターゲットグループに対する接続は可能かどうかをチェックしたほうがお勧めします。
**つまり、ターゲットのセキュリティグループに、ALBからのトラフィックを許容してあるかどうかを優先チェックした方が良いです。**

AWS公式ドキュメントは、ALBの502エラーコードの考えられる原因がまとまっています。
>考えられる原因:
・接続の確立を試みているときに、ロードバランサーがターゲットから TCP RST を受信した。
・接続の確立を試みているときに、ロードバランサーがターゲットから予期しないレスポンスを受信した (例: 「ICMP Destination unreachable (Host unreachable) (ICMP 送信先に到達できません (ホストに到達できません))」など)。ターゲットポートでロードバランサーサブネットからターゲットへのトラフィックが許可されているかどうかを確認します。
・ロードバランサーにターゲットへの未処理のリクエストがあるときに、ターゲットが TCP RST または TCP FIN との接続を閉じた。ターゲットのキープアライブ期間がロードバランサーのアイドルタイムアウト値よりも短いことを確認します。
・ターゲットのレスポンス形式が正しくないか、有効でない HTTP ヘッダーが含まれている。
・ロードバランサーがターゲットに接続するときに、SSL ハンドシェイクエラーまたは SSL ハンドシェイクタイムアウト (10 秒) が発生しました。
・登録解除されたターゲットによって処理されていたリクエストで登録解除の遅延期間が経過しました。時間のかかるオペレーションが完了できるように、遅延期間を増やします。
・ターゲットは Lambda 関数で、レスポンスボディが 1 MB を超えています。
・ターゲットは、設定されたタイムアウトに達する前に応答しなかった Lambda 関数です。
・ターゲットとなるのは、エラーを返した Lambda 関数、または Lambda サービスがスロットリングした関数です。

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html#http-502-issues

# HTTP 503: Service unavailable
Wikipediaから参考すると、503エラーコードの意味は以下となります。
>503 Service Unavailable
>The server cannot handle the request (because it is overloaded or down for maintenance). Generally, this is a temporary state.[64]

503エラーコードにありましたら、
**ALBターゲットグループに、対象ターゲットが正しく「Registered targets」に登録されたかどうかを、チェックした方が良いです。**

AWS公式ドキュメントは、ALBの503エラーコードの考えられる原因がまとまっています。
>考えられる原因:
・ロードバランサーは、接続タイムアウトが期限切れになる (10 秒) 前にターゲットへの接続の確立に失敗した。
・ロードバランサーはターゲットへの接続を確立したが、アイドルタイムアウト期間が経過する前にターゲットが応答しなかった。
・サブネットのネットワーク ACL で、ターゲットから一時ポート (1024-65535) のロードバランサーノードへのトラフィックが許可されなかった。
・ターゲットがエンティティ本文より大きな Content-Length ヘッダーを返した。ロードバランサーが欠落しているバイトを待機してタイムアウトした。
・ターゲットは Lambda 関数であり、接続タイムアウトが期限切れになる前に Lambda サービスが応答しませんでした。

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html#http-503-issues

# HTTP 504: Gateway Timeout
Wikipediaから参考すると、504エラーコードの意味は以下となります。
>504 Gateway Timeout
>The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.[65]

こちらはALB後ろのターゲットへのコネクションが失敗してしまうによるエラー可能性が高いです。
なので、ALBのターゲットグループの設定を優先的に見直す必要があります。
**例えばターゲットグループはEC2であれば、EC2上のアプリケーション側の設定が失敗してしまいそうとか、その起因によるエラーかもしれません。**
もちろん、EC2側の問題だけではありません、上記はあくまで例であります。

AWS公式ドキュメントは、ALBの504エラーコードの考えられる原因がまとまっています。
>考えられる原因:
・ロードバランサーは、接続タイムアウトが期限切れになる (10 秒) 前にターゲットへの接続の確立に失敗した。
・ロードバランサーはターゲットへの接続を確立したが、アイドルタイムアウト期間が経過する前にターゲットが応答しなかった。
・サブネットのネットワーク ACL で、ターゲットから一時ポート (1024-65535) のロードバランサーノードへのトラフィックが許可されなかった。
・ターゲットがエンティティ本文より大きな Content-Length ヘッダーを返した。ロードバランサーが欠落しているバイトを待機してタイムアウトした。
・ターゲットは Lambda 関数であり、接続タイムアウトが期限切れになる前に Lambda サービスが応答しませんでした。

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html#http-504-issues

# HTTP 400: Bad request
このエラーはクライアント側のエラーになります。
多くの場合は、クライアントからHTTPに満たさないリクエストを投げた際に、このエラーが表示されます。
**例えばリクエストが長すぎてしまったとか、もしくはリクエストに何かが漏れてしまったとかが原因でありそうです。**

AWS公式ドキュメントは、400エラーコードの考えられる原因がまとまっています。
>考えられる原因:
・クライアントが HTTP 仕様を満たさない誤った形式のリクエストを送信した。
・リクエストヘッダーが、リクエスト行あたり 16K、1 つのヘッダーあたり 16K、またはヘッダー全体に対して 64K を超えている。

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html#http-400-issues

# HTTP 403: Forbidden
**こちらはWAFによってブロックされた際に、出て来るエラーコードになります。**

AWS公式ドキュメントは、403エラーコードの考えられる原因がまとまっています。
>考えられる原因:
Application Load Balancer へのリクエストをモニタリングするよう AWS WAF ウェブアクセスコントロールリスト (ウェブ ACL) を設定し、リクエストがブロックされました。

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html#http-403-issues

# HTTP 408: Request timeout
**定められた一定期間に、クライアント側がデータを送信していなかった場合は、このエラーが表示されます。**
例えば何かネット上でチケットを予約する際に、XX分以内に手続きを済ませなかったら、チケットの購入が無効になるとかの場合に、このエラーが表示されかねません。

AWS公式ドキュメントは、408エラーコードの考えられる原因がまとまっています。
>考えられる原因:
・アイドルタイムアウト期間の期限が切れる前に、クライアントからデータが送信されませんでした。TCP キープアライブを送信しても、このタイムアウトを防ぐことはできません。各アイドルタイムアウト期間が経過する前に、1 バイト以上のデータを送信します。必要に応じて、アイドルタイムアウト期間を長くします。

# HTTP 464
**リクエストプロトコルが許容されていない場合は、このエラーが表示されます。**

AWS公式ドキュメントは、464エラーコードの考えられる原因がまとまっています。
>考えられる原因:
・リクエストプロトコルは HTTP/1.1 であるが、ターゲットグループのプロトコルバージョンが gRPC または HTTP/2 である。
・リクエストプロトコルは gRPC であるが、ターゲットグループのプロトコルバージョンが HTTP/1.1 である。
・リクエストプロトコルは HTTP/2 であり、リクエストは POST ではないが、ターゲットグループのプロトコルバージョンが gRPC である。

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html#http-464-issues

# まとめ
まとめると、4XX、5XXエラーコードに遭った際に、
AWS上、もしくはクライアント側で、以下の設定項目を優先的にチェックすることを推奨いたします。

|エラーコード             |	設定の見直し先   |
|:------------------|:------------------|
|HTTP 502: Bad gateway|ターゲットのセキュリティグループに、ALBからのトラフィックを許容してあるかどうか|
|HTTP 503: Service unavailable|ALBターゲットグループに、対象ターゲットが正しく「Registered targets」に登録されたかどうか|
|HTTP 504: Gateway Timeout|ターゲットグループ上のアプリケーション設定|
|HTTP 400: Bad request|クライアント側からリクエストしたHTTP形式が正確かどうか|
|HTTP 403: Forbidden|WAFの設定がクライアントからのアクセスを許容するかどうか|
|HTTP 408: Request timeout|定められた一定期間に、クライアント側がデータを送信したかどうか|
|HTTP 464|リクエストのプロトコルが許容されるかどうか|