Lambda関数は成功するのにAPI Gatewayからは「Internal Server Error」

AWS Lambdaを使って処理を自動化し、API GatewayからそのLambda関数を呼び出す構成は、サーバーを持たずにAPIを公開する方法としてとても人気です。

しかし、Lambda関数はテストでは正常に動作するのに、API Gatewayを通してアクセスすると「Internal Server Error」というエラーが返ってくるケースが多くあります。
本記事では、そのようなときに考えられる原因と解決方法を、実例を交えて詳しく解説します。

よくある原因:Lambda関数自体は問題なし

まず、Lambda関数単体のテストで成功しているということは、関数のロジックや実行環境には大きな問題がないと考えられます。
しかし、API Gateway経由で呼び出したときに「内部サーバーエラー」が返る場合、Lambda関数の外側の設定、つまりAPI Gatewayの設定や連携方法に原因があることがほとんどです。

レスポンス形式の不備

API Gateway経由でLambda関数を実行する場合、Lambda関数の返す応答の形式に注意が必要です。
API Gatewayは、特定の形式のレスポンスを期待しています。

例えば、以下のような正しい形式でレスポンスを返す必要があります。

return {
  statusCode: 200,
  headers: {
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ message: "成功しました" })
};

このように、statusCodeheadersbodyを含む構造が必要です。

もしこれらのいずれかが欠けていると、API Gatewayは「内部エラー」として扱い、クライアントに500番エラーを返すことがあります。

統合レスポンスの設定ミス

API Gatewayの設定画面には、Lambda関数との「統合レスポンス」という項目があります。
この設定が正しくないと、Lambda関数が正しく処理していても、API Gateway側でレスポンスの扱いに失敗します。

とくにLambdaプロキシ統合(proxy integration)を使っている場合は、Lambda関数の戻り値の形式が正しくないと失敗します。
一方で、プロキシ統合を使っていない場合は、マッピングテンプレートなどを設定する必要があります。

IAMロールの権限不足

API GatewayがLambda関数を呼び出すためには、アクセス権限が必要です。
通常、API GatewayからLambdaを呼び出す場合は、IAMロール(実行ロール)が自動で付与されますが、手動で設定を変更していると、呼び出しに失敗することがあります。

その場合、API Gatewayの設定で使われているロールがLambda関数にアクセスできるかを確認しましょう。

Lambda関数のタイムアウト

Lambda関数が重い処理を行っている場合、タイムアウトによって失敗している可能性もあります。
Lambda関数のデフォルトのタイムアウトは3秒です。
外部のデータベースへの接続やファイルの読み込みなど、処理に時間がかかる場合は、タイムアウトを10秒以上に延長してみてください。

タイムアウトした場合も、Lambda関数はエラーを返さず終了し、API Gatewayでは「Internal Server Error」となります。

Lambda関数での例外処理漏れ

Lambda関数内で発生したエラーがtry-catchで捕まえられていないと、エラーがそのまま投げられてしまい、API Gateway側では「500 Internal Server Error」として処理されます。

以下のように、例外処理を適切に行いましょう。

exports.handler = async (event) => {
  try {
    // メインの処理
    return {
      statusCode: 200,
      body: JSON.stringify({ message: "成功です" })
    };
  } catch (error) {
    console.error("エラーが発生しました", error);
    return {
      statusCode: 500,
      body: JSON.stringify({ message: "サーバーエラー" })
    };
  }
};

API Gatewayのステージ未デプロイ

設定を変更した後、デプロイを行わないと変更が反映されません。
API Gatewayのコンソールで、ステージへのデプロイを必ず行ってください。

実装例

以下は、Lambda関数が正常にAPI Gatewayと連携するための最小構成の例です。

exports.handler = async (event) => {
  const name = event.queryStringParameters?.name || "ゲスト";

  return {
    statusCode: 200,
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ message: ${name}さん、こんにちは! })
  };
};

このコードは、クエリ文字列から名前を取得して挨拶を返すものです。
API Gatewayでは、GETメソッドに対応させて、クエリパラメータ付きのURLで動作確認ができます。

まとめ

Lambda関数が単体で動くのに、API Gateway経由では「Internal Server Error(内部サーバーエラー)」が返ってくる原因は、Lambda関数側ではなくAPI Gatewayとの連携部分にあることがほとんどです。

特に確認すべきポイントは以下の通りです。

  • レスポンス形式が正しいか(statusCode, body など)
  • 統合レスポンスの設定に誤りがないか
  • 権限(IAMロール)が適切に設定されているか
  • タイムアウト未処理のエラーがないか
  • ステージのデプロイ忘れがないか

これらを1つずつ確認することで、問題の特定と解決がしやすくなります。

最後に

このような構成では、LambdaAPI Gatewayという異なる仕組みを組み合わせているため、細かい設定のミスや見落としがエラーにつながります。
特に「内部サーバーエラー」のように原因が見えにくい場合は、ログ出力構成の見直しがとても重要です。

トラブルシューティングの基本は「1つずつ切り分けること」。
焦らず、丁寧に確認していきましょう。

もしこの記事が参考になったら、ぜひ他の記事も読んでみてください!
現場で役立つAWSやサーバーレス技術の解説を、わかりやすくお届けしています。


Amazonベストセラー

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA