API Gateway(REST API)+Lambdaの構成の際にペイロードサイズ制限を超えた場合、500エラーがまれに返却される件
はじめに
Amazon API Gateway(以下、API Gateway)とAWS Lambda(以下、Lambda)の組み合わせで、予想外の動作を確認しました。この記事では、その問題についてサポートに問い合わせた結果を共有します。
問い合わせの内容
不具合について
API Gateway にLambdaプロキシ統合の機能を使ってLambdaと連携をさせた場合にペイロードサイズ制限を超えた6MB以上のデータを送信するとHTTPステータスコード413エラーで返却されます。これは想定されている動作になりますが、まれにHTTPステータスコード500エラーが返却される場合があります。
※ペイロードサイズ制限について
- API Gatewayのクオーターは4MB(https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/limits.html)
- Lambdaの同期呼び出しの場合のペイロードサイズは6MB(https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/gettingstarted-limits.html)
検証したところ完全にランダムということではなく、1回目は413のエラーで連続でペイロードサイズ制限を超えたパラメータを送信すると500エラーに変わるような動きになります。数分時間を空けて再度試すと413のエラーがまずを返却され、以降前述のとおり500エラーが返却されるような動きとなっていました。
結論
結論を先に書きますと、
2023/04/09時点の回答では、AWS側でも把握してる事象で原因調査中とのことでした。
なお、2023/5/28時点では解消はされていません。
AWS側の推奨としては、6MBを超えるペイロードを処理させたい場合は、S3バケットなどに一度格納してから処理をやってほしいとのことでした。
不具合の再現
再現手順
事象自体の発覚は弊社サービスで利用しているAPIで実装中に発覚しましたが、問題の切り分けとしてPOSTメソッドを受け取りテキストを返却するだけのシンプルなAPIGateway+Lambdaの構築をserverless frameworkで行い、サポートに問い合わせを行いました。
問い合わせに使用したリポジトリを使い説明を進めて行きます。
構成
今回作成するリソースは以下になります。
■APIGatewayの設定
- プロトコル:REST
- エンドポイントタイプ:Edge
- パス:/
- メソッド:POST
- 統合リクエスト:LAMBDA_PROXY
■Lambda
- 関数名:simple-api-dev-hello
- リージョン:ap-northeast-1
- ランタイプ:Node.js 14.x
- リージョン: ap-northeast-1
- API Gateway のタイプ: REST API
起動手順
※aws configureは設定済みとして進めて行きます。
- 以下GitHubリポジトリをクローンしてきて、初回インストールを行う。
git clone git@github.com:RysSuzuki/simple-api-for-quota-validation.git
npm ci
- API GatewayとLambdaのデプロイ
cd packages/simple-api
npx serverless deploy
- 構築したAPI Gatewayに5MBのBASE64データを含んでリクエストを送信する。
※送信するデータは5MBのダミーファイルをBASE64形式に変換した値を送信します。
cat ../../base64_5mb | \
curl -i -X POST <API Gatewayのendpoint> -H "Content-Type:application/json" -d @-
送信結果
413のエラーが想定される挙動になりますが、まれに500エラーが返却されます。
- 正常な返却値
HTTP/2 413
content-type: application/json
content-length: 31
----略----
{"message": "Request Too Long"}
- 想定外の返却値
HTTP/2 500
content-type: application/json
content-length: 36
----略----
{"message": "Internal server error"}
まとめ
今回は大きなファイルを送信する必要がなかったため、推奨されていないものの、Base64形式で送信する方法を採用しました。
ただし、推奨されない実装方法を選択した場合、今回のような問題に直面したときに対応を受けられないリスクも存在します。
400系と500系エラーだとユーザーに表示するメッセージや運営側のアラート対応が変わってくるので、早めに修正されることを願ってます。
Discussion