Lambda 関数の呼び出し(Invoke)で TooManyRequestsException(429)が返りました。再試行しても二重に実行されませんか。

Lambda 関数の呼び出し(Invoke)で TooManyRequestsException(429)が返りました。再試行しても二重に実行されませんか。

Lambda の同期呼び出しで `TooManyRequestsException` エラーが発生したとき、再試行で関数が二重実行されるのかについて確認してみました。実際の検証結果をもとに、エラー時の適切な対応方法を紹介します。
2026.10.27

困っていること

Lambda 関数を、AWS CLI や AWS SDK から同期呼び出し(Invoke)しています。
呼び出しが集中したときに、次のエラーが返りました。
このエラーの後に呼び出しを再試行すると、関数が二重に実行されないか教えてください。

aws: [ERROR]: An error occurred (TooManyRequestsException) when calling the Invoke operation (reached max retries: 0): Rate Exceeded.

Additional error details:
Type: User
Reason: ConcurrentInvocationLimitExceeded

どう対応すればいいの?

429 が返った呼び出しは、再試行しても二重には実行されません。関数を実行する前に、Lambda が拒否した呼び出しだからです。
ただし、クライアント側のタイムアウトの後に再試行した場合は、関数が二重に実行されることがあります。次の 3 つの対策を行ってください。

  1. 429 の再試行は、AWS CLI や SDK の自動の再試行に任せます。AWS CLI v2 のデフォルトの standard モードでは、TooManyRequestsException は再試行の対象で、指数バックオフで再試行されます。自前で再試行する場合は、指数バックオフとジッター(待ち時間のばらつき)を入れ、回数に上限を付けます。
  2. クライアント側のタイムアウト(AWS CLI なら --cli-read-timeout。デフォルトは 60 秒)を、関数のタイムアウトより長くします。
  3. 関数のコードを冪等(同じイベントを何度処理しても結果が同じ)にします。リクエストごとの冪等性キー(注文の ID など)を、「処理中」「完了」の状態と一緒に記録します。完了済みのキーは処理せず、前の結果を返します。処理に失敗したときは、記録を消すか期限を付けて、再試行で処理し直せるようにします。

なぜ二重に実行されないのか

TooManyRequestsException(HTTP 429)は、同時実行数のクォータを超えたときに、Lambda が関数を実行せずに返すエラーです。

https://docs.aws.amazon.com/ja_jp/lambda/latest/api/API_Invoke.html

例えば、関数の実行がアカウントレベル (ConcurrentInvocationLimitExceeded) または関数レベル (ReservedFunctionConcurrentInvocationLimitExceeded) のいずれかで同時実行制限を超過する原因となる場合、Lambda は TooManyRequestsException を返します。

タイムアウトの後の再試行に注意

AWS CLI と AWS SDK は、スロットリングだけでなく、クライアント側のタイムアウトでも自動で再試行します。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/invocation-sync.html

また、AWS CLI と AWS SDK は、クライアントのタイムアウト、スロットル、およびサービスエラーで自動的に再試行します。

クライアント側のタイムアウトは、呼び出す側が、設定した時間内に応答を受け取れずに接続を切ることです。関数のタイムアウトとは別の設定です。このとき関数はすでに実行されている場合があるので、再試行で関数が複数回呼び出されることがあります(今回は試していません)。対策 2 と 3 は、このためのものです。

429 が続く場合

アカウントや関数の同時実行数を確認してください。アカウントの同時実行数のクォータは、aws lambda get-account-settings の出力の AccountLimit.ConcurrentExecutions で確認できます。デフォルトは 1,000 ですが、新しいアカウントでは低く設定されています。
拒否された呼び出しの数は、Lambda のコンソールの「Event Functions」で関数を開き、「モニタリング」タブの「スロットリング」のグラフで確認できます。

確認してみた

同時実行数のクォータが 10 の検証用のアカウント(東京リージョン)で試しました。予約済み同時実行数を設定していない、10 秒待つだけの Lambda 関数(Python 3.13)に、12 個の呼び出しを同時に送りました。

冒頭のエラーと同じ形で確かめるため、AWS CLI の再試行を無効にして(AWS_MAX_ATTEMPTS=1)実行しました。

export AWS_MAX_ATTEMPTS=1
for i in $(seq 1 12); do
  ( aws lambda invoke --function-name blog-01-fn --cli-binary-format raw-in-base64-out \
      --payload "{\"id\":$i}" --cli-read-timeout 60 --debug /dev/null 2>&1 \
    | grep -E 'HTTP/1\.1" [0-9]{3}|An error occurred|^Type:|^Reason:|"StatusCode"' > inv-$i.txt ) &
done; wait

12 個のうち 2 個が、「困っていること」と同じ TooManyRequestsException のエラーで拒否されました。--debug の出力では、拒否された 2 個の応答は HTTP 429、ほかの 10 個は 200 でした。次の画像は、inv-9.txt・inv-10.txt・inv-1.txt に見出しを付けて、順に表示したものです。

01

関数のログに残った呼び出しは 10 個で、拒否された 2 個は実行されていませんでした。予約済み同時実行数は設定しておらず、Reason は ConcurrentInvocationLimitExceeded だったので、アカウントの同時実行数のクォータ(10)に当たったと判断しました。

コンソールの「モニタリング」タブでも、「呼び出し」は 10、「スロットリング」は 2 でした。次の画像は、同じ条件で先に行った検証のグラフで、数は上の検証と同じです。

02

参考資料


AWSテクニカルサポートノートについて

過去にクラスメソッドのAWS総合支援サービスで頂いたお問合せの中から、通常のAWS利用時でも有益になりうる情報をテクニカルサポートチームがTIPSとしてご紹介しています。技術サポートは、無料でご提供しております。詳細は下記ボタンからご覧ください。

クラスメソッドのAWSサポートの詳細を見る

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事