AthenaのTABLE_NOT_FOUND、Webコンソールは通るのにLambdaだけ失敗する

  • AWS
  • Athena
  • Glue
  • Lambda
  • IAM

この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。

何が起きたか

Glueデータベースはすでに作成済みで、Athenaのクエリも example_db.access_logs のようにデータベース名・テーブル名を正しく指定してる。それなのに

TABLE_NOT_FOUND: line 6:9: Table 'awsdatacatalog.example_db.access_logs' does not exist

というエラーが返ってきた。ただし条件があって、AWSコンソールのAthenaエディタから直接同じクエリを実行すると成功する。Lambda(Node.js)から StartQueryExecutionCommand で実行したときだけ失敗する。

疑ったこと

最初はGlueテーブル自体が存在してないのかと思ったけど、コンソールから成功してる時点でテーブルはちゃんとある。となると怪しいのは「実行主体が違う」ところ。コンソールは自分のIAMユーザー権限で動くけど、Lambdaは自分専用のIAM実行ロールで動く。

flowchart LR
    A[Athenaクエリ] --> B{実行主体}
    B -->|Webコンソール| C[IAMユーザー権限]
    B -->|Lambda| D[Lambda実行ロール]
    C --> E[成功]
    D --> F[TABLE_NOT_FOUND]

原因

Lambdaの実行ロールに、Athenaの実行権限(athena:StartQueryExecutionなど)はあってもGlue Data Catalogへのアクセス権限が無いケースだった。

本来、Glue側の権限が無い場合は AccessDeniedException(glue:GetTable is not authorized のようなメッセージ)が返るのが素直な挙動らしい。ただし実際には、Lambda実行ロールにGlue権限が不足しているケースで TABLE_NOT_FOUND として表面化する報告も複数あるらしい(AWS公式ドキュメントで明言されているわけではなく、コミュニティのトラブルシュート情報ベース。実機で「権限を外した状態」を再現して確認したわけではない)。

必要だった権限は大きく3つ。

Athena

  • athena:StartQueryExecution
  • athena:GetQueryExecution
  • athena:GetQueryResults
  • athena:GetWorkGroup
  • athena:StopQueryExecution

Glue Data Catalog

  • glue:GetDatabase
  • glue:GetDatabases
  • glue:GetTable
  • glue:GetTables
  • glue:GetPartition
  • glue:GetPartitions

S3(クエリ結果保存用バケット)

  • s3:GetObject
  • s3:PutObject
  • s3:ListBucket

Athenaの実行権限だけ付けてGlue側の権限を付け忘れる、というのはありがちなミスパターンだった。

切り分け方

コンソールとLambdaで結果が変わるときは、まず「実行ロールが違う」ことを疑うのが早い。具体的には、Lambda実行ロールから glue:GetTable だけ意図的に外してみて、同じ TABLE_NOT_FOUND が再現するか確認する。

  • 再現する → 権限起因の可能性が高い
  • 再現しない → QueryExecutionContext の Database / Catalog 指定ミスや、データベース名・テーブル名の大文字小文字の不一致を疑う

今回は QueryExecutionContext の指定自体は合ってたので、Glue権限を追加したら解消した。