この記事について
こんにちは!
ビジネスエンジニアリング株式会社の髙橋と申します!
本記事は、
Japan AWS Jr. Champions Advent Calendar 2025
4日目の記事となります。
はじめに
SaaS型サービスの定期メンテナンス機能を開発していたところ、長期間実行されていないVPC Lambda関数が ResourceNotReadyException を引き起こす事象に遭遇しました。
本記事の結論として、これはVPC接続のLambdaが長期間呼び出されないことでENI(Elastic Network Interface)が解放されてしまい、次に呼び出された際に再接続(ENI作成)が完了するまでリクエストを受け付けられない状態になることに起因します。
本記事では、この現象を「VPC Lambda冬眠問題」と定義し、その原因と対策について解説します。
発生した事象
Step Functionsを用いた定期メンテナンス処理を実行したところ、ワークフロー内のLambdaで以下のエラーが発生しました。
ResourceNotReadyException
システム構成概要
処理の全体像は以下の通りです。EventBridge Schedulerをトリガーに、Step Functionsが起動し、VPC内のLambdaを同期呼び出し(結果が返るまで待機)する構成でした。
上記は一連の処理を簡略化した概要図です。
原因の特定
調査の結果、原因は「Lambda関数が約3週間実行されておらず、Inactive状態(冬眠状態)になっていたこと」でした。
興味深いことに、エラー発生直後に再度実行したところ、今度は正常に処理が完了しました。
原因の詳細:Inactive状態とENIの再作成
なぜ Inactive になるのか
VPCに接続されているLambda関数は、長期間(数週間以上)呼び出されないと、AWSによってリソース効率化のためにネットワークインターフェイス(ENI)が解放され、ステータスが Inactive 状態に移行します。
AWS公式ブログ「AWS Lambda関数の状態の追跡」によると、「数週間(weeks)呼び出されないとInactive状態に移行する可能性がある」とされています(コミュニティでの観測や一部の記事では、約14日間程度と言われています)。
「なぜ待ってくれないのか? AWSの設計ミスではないか?」と感じるかもしれませんが、これはVPCリソース(IPアドレスやENI)を無限に占有しないための仕様(リソース効率化のトレードオフ)です。
AWS公式のナレッジセンター記事「Lambda の 502 エラーと 500 エラーのトラブルシューティング」には、以下のように明記されています。
Lambda は、使用されていないネットワークインターフェイスを解放します。 このアクションにより、関数を非アクティブ状態にすることができます。
つまり、アイドル状態が続いた関数から外部リソース(ENI)が回収されること、およびその復帰時にエラー(ResourceNotReadyException)が発生する場合があることは、プラットフォームの仕様通りの挙動です。
なぜエラーになるのか(必発性について)
Inactive 状態のLambda関数を呼び出すと、Lambdaサービスは即座にENIの再作成を開始し、ステータスを Pending(準備中)に変更します。
この際、ENIの作成完了を待たずに呼び出し自体は失敗し、ResourceNotReadyException が返されます。
つまり、ENIが解放されている状態で同期的に呼び出しを行うと、初回はほぼ確実にこのエラーが発生します。
VPC Lambda特有の問題である理由
このエラーは、その名の通り「必要なリソース(Resource)の準備ができていない(NotReady)」ことを示していますが、ここで言う「リソース」とは、主にENI(Elastic Network Interface)を指します。
通常の(VPCに接続しない)Lambdaと、VPC Lambdaでは、起動プロセスに以下の決定的な違いがあります。
- VPCなし Lambda: 計算リソース(MicroVM)を確保するだけで起動できる。
- VPCあり Lambda: 計算リソースに加え、VPCと通信するためのネットワークインターフェイス(ENI)を作成・接続する必要がある。
VPC Lambdaのアーキテクチャについては、AWS Compute Blogの記事「Announcing improved VPC networking for AWS Lambda functions」で詳しく解説されていますが、VPCリソースへアクセスするためにはHyperplane ENIと呼ばれる専用のインターフェイスが必要です。
Inactive状態からの復帰時、この「ENIの作成とアタッチ」という追加のプロセスが発生します。この処理はコントロールプレーン側で行われるため時間がかかる場合があり、即座に応答を返さなければならない同期呼び出しにおいて「準備が間に合わない」と判断され、エラーとなります。
そのため、ENI作成プロセスが存在しない「VPCなしLambda」では、このエラーは発生しません。
特に以下のようなケースでは注意が必要です。
- VPCに接続されている
- 実行頻度が低い(数週間に1回、月に1回など)
- 同期呼び出しを行っている(Step FunctionsやAPI Gateway経由など)
対策
この問題に対する対策をいくつか紹介します。
対策①:定期的な実行(ウォーミングアップ)
EventBridgeを利用して、対象のLambdaを週に1回など、冬眠させない(ENIを解放させない)頻度で定期的に実行します。
AWS公式ブログ「AWS Lambda関数の状態の追跡」では、「関数を定期的に呼び出すことでActive状態を維持できる」と推奨されています。
メリット
- エラーの発生を根本的に防げる(常に
Active状態を維持)
デメリット
- わずかな実行コストが発生する
- 定期実行用のリソース管理が必要になる
- ログが増える(実際の処理ログとの区別が必要になる)
対策②:リトライ処理の実装
最も有効かつ一般的な対策は、エラー発生時に少し時間を置いて再実行させる「リトライ処理」の実装です。
呼び出し方式によって、標準の挙動が異なるため注意が必要です。
1. 非同期呼び出しの場合(EventBridge, S3トリガーなど)
もしLambdaを「非同期(Event)」で呼び出している場合、追加の設定は不要です。
AWS公式ドキュメント「AWS Lambda における非同期呼び出しのエラー処理」には、以下の仕様が明記されています。
関数を実行できない場合 (たとえば、並列数が足りない場合)、Lambda は最大 6 時間リクエストをキューに入れてリトライします。
今回の ResourceNotReadyException は、コードが実行される前(ENI作成待ち)に発生するエラーであり、上記の「関数を実行できない場合」に該当します。 そのため、コード実行エラー用の「再試行回数(デフォルト2回)」の設定値に関わらず、Lambdaサービス側がENI作成完了まで自動的にリトライを継続してくれます。
結果として、ENIの準備が整ったタイミングで処理が実行されるため、ユーザー側での特別なハンドリングは不要です。
2. 同期呼び出しの場合(Step Functions, API Gatewayなど)
今回の事例のように Step Functions から呼び出す場合、通常は「同期(RequestResponse)」扱いとなるため、Lambda側の自動リトライは行われません。エラーが即座に呼び出し元へ返却されます。
そのため、呼び出し元(Step Functions)側で「待機してから再実行する」設定を明示的に入れる必要があります。
AWS公式ドキュメント「ResourceNotReadyException のトラブルシューティング」でも、解決策として「待機してから再度呼び出す」手順が示されています。
Step Functionsでの設定例:
"Retry": [
{
"ErrorEquals": ["ResourceNotReadyException", "Lambda.TooManyRequestsException"],
"IntervalSeconds": 60,
"MaxAttempts": 3,
"BackoffRate": 2.0
}
]
補足: ENIの作成には数十秒かかる場合があるため、IntervalSeconds(再試行間隔)は少し長めに設定するか、BackoffRate を設定して徐々に待機時間を延ばすのがコツです。
メリット
-
実装コストが低い(設定のみ)
-
Pending から Active への移行は通常数十秒で完了するため、リトライで救える可能性が高い
デメリット
- 1回目のエラー自体は発生するため、ログ監視の設定によってはアラートが発報される可能性がある(「リトライで成功すればOK」とする監視設計が必要)
対策③:プロビジョニング済み同時実行(Provisioned Concurrency)の設定
Lambdaの「プロビジョニング済み同時実行」機能を有効にすることで、常に初期化された実行環境(およびENI)を維持することができます。
AWS公式ドキュメント「プロビジョニング済み同時実行」およびCompute Blog「Announcing improved VPC networking for AWS Lambda functions」では、この機能が実行環境を初期化し、ネットワークインターフェイス(ENI)のセットアップを含む準備プロセスを完了させ、即座に応答可能な状態を維持すると説明されています。したがって、この設定が有効である限り、ENIが破棄されてInactive状態になることはありません。
メリット
- 常にホットスタンバイ状態となるため、冬眠問題(Inactive状態)を確実に回避できる
- コールドスタート自体が発生しないため、実行開始が非常に高速
デメリット
- コストが高い / コスト効率が悪い:技術的には確実な解決策ですが、関数が実行されていない待機時間も含めて課金が発生します。今回のような「月に数回のバッチ」のために常時課金するのはコスト対効果が悪く、通常は即応性が求められるWeb APIなどで利用される機能です。
対策④:代替サービスの検討
エラーを完全に回避し、かつ即応性が求められる場合は、ECS (Fargate) や常時稼働のEC2など、VPC接続の冬眠問題が発生しないサービスの利用を検討するのも一つの手です。
メリット
- 冬眠問題が根本的に発生しない
デメリット
- Lambdaと比較してコストや運用管理の負担が増えるケースが多い
まとめ
VPCに接続された実行頻度の低いLambda関数では、VPC Lambda特有の冬眠問題(Inactive状態からの復帰)により ResourceNotReadyException エラーが発生する可能性が高いです。
システムが許容できる「遅延」や「運用制約」に応じて、以下の対策を選択してください。
- 多少の遅延は許容できる → リトライ処理の実装(推奨)
- 絶対にエラーを出したくない(低コスト) → 定期実行(ウォーミングアップ)
- 絶対にエラーを出したくない(定期実行がNGな場合) → プロビジョニング済み同時実行
- アーキテクチャを見直す → ECS等の利用
参考リンク
- プロビジョニング済み同時実行 (AWS Lambda 開発者ガイド)
- Announcing improved VPC networking for AWS Lambda functions (AWS Compute Blog)
- ResourceNotReadyException のトラブルシューティング (AWS re:Post)
- AWS Lambda関数の状態の追跡 (AWSブログ)
- AWS Lambda における非同期呼び出しのエラー処理 (AWS Lambda 開発者ガイド)
- Lambda 関数の Inactive 状態を回避するにはどうすればよいですか? (DevelopersIO)
