このブログでは、管理者が記事の編集画面でボタンを押すと Amazon Bedrock を使って記事の要約やタグ候補を自動生成する Lambda を動かしています。
先日この Lambda で要約やタグ候補の生成を実行すると「成功したり失敗したりする」という断続的なエラーが発生しました。 原因を調査した際のメモを残しておきたいと思います。

発生していたエラーは以下のような内容でした。
AccessDeniedException: Model access is denied due to IAM user or service role is not authorized
to perform the required AWS Marketplace actions
(aws-marketplace:ViewSubscriptions, aws-marketplace:Subscribe)
to enable access to this model.
エラー自体は AccessDeniedException で、メッセージに aws-marketplace:ViewSubscriptions, aws-marketplace:Subscribe とあります。
これは Bedrock でモデルを利用するために必要な AWS Marketplace サブスクリプションが不足している場合に発生するエラーのようです。
ただし、常に失敗するわけではなく「成功したり失敗したりする」という断続的な挙動だったため、権限ではなく別のところに問題がある可能性を最初は疑いました。
このシステムでは、コスト効率とスループット確保のために jp.anthropic.claude-haiku-4-5-20251001-v1:0 という Japan cross-region inference profile を使っています。
この inference profile は、リクエストを以下の 2 つのリージョンに 動的にルーティング する仕様になっているようです。 (参考: Increase throughput with cross-Region inference)
dynamically routing model invocation requests across the Regions defined in inference profile
| リージョン | 状態 |
|---|---|
| ap-northeast-1 (東京) | 特に申請した覚えはないが、なぜか正常に処理されていた (過去のどこかで初回実行済みだったと考えられる) |
| ap-northeast-3 (大阪) | 一度も実行されていなかった → 403 エラー |
実際の挙動としては、UI から生成をリクエストすると「1回目は成功、2回目は失敗」というような交互に成功・失敗するパターンが確認できました。
これは inference profile が 2 リージョンに交互にルーティングしており、東京へのルーティング時は成功し、大阪へのルーティング時は 403 で失敗していたためと考えられます。
どちらのリージョンにルーティングされたかは CloudWatch ログから直接確認できるわけではなく、以下の状況証拠から推論しています。
Marketplace モデルは、Marketplace 権限を持つユーザーがリージョンごとに一度実行することでアカウント全体に有効化される仕様になっています。
東京は過去のどこかのタイミングでその初回実行されていた?と考えられますが、大阪では一度も実行されていなかったため 403 になっていたと考えると腑に落ちました。
まず、大阪リージョンでモデルを直接呼び出してみると、以下の ValidationException が返りました。
aws bedrock-runtime converse \
--region ap-northeast-3 \
--model-id anthropic.claude-haiku-4-5-20251001-v1:0 \
--messages '[{"role":"user","content":[{"text":"hi"}]}]'
# => ValidationException: Invocation of model ID ... with on-demand throughput isn't supported.
# Retry your request with the ID or ARN of an inference profile that contains this model.
どうやら inference profile を経由しないと直接呼び出せない仕様のため、jp.* inference profile 経由で東京から呼び出してみると、今度は 403 が返りました。
aws bedrock-runtime converse \
--region ap-northeast-1 \
--model-id jp.anthropic.claude-haiku-4-5-20251001-v1:0 \
--messages '[{"role":"user","content":[{"text":"hi"}]}]' \
--query 'output.message.content[0].text' \
--output text
# => AccessDeniedException: aws-marketplace:ViewSubscriptions, aws-marketplace:Subscribe ...
jp.* inference profile 経由で呼び出すと 403 が返ることが確認できました。
よって、大阪リージョンへのルーティング時にモデルアクセスが通ればおそらく解決するのではと考えました。
AWS コンソールのリージョンを ap-northeast-3 (大阪) に切り替え、Bedrock Playground から Claude Haiku 4.5 を実行しました。
初回実行時に AWS Marketplace サブスクリプションが自動作成されることで、大阪リージョンへのルーティング時にも正常に処理が通るようになるのかと思われます。
Playground 実行後に再度 CLI でテストしたところ、正常応答が確認できました。

aws bedrock-runtime converse \
--region ap-northeast-1 \
--model-id jp.anthropic.claude-haiku-4-5-20251001-v1:0 \
--messages '[{"role":"user","content":[{"text":"hi"}]}]' \
--query 'output.message.content[0].text' \
--output text
# => Hey there! 👋 How's it going? What can I help you with today?
今後の類似問題を防ぐために、Lambda の実行ロールに Marketplace 権限を追加しました。
# infra/service/batch/article_llm/iam.tf
resource "aws_iam_role_policy" "bedrock_marketplace" {
...
condition {
test = "StringEquals"
variable = "aws:CalledViaLast"
values = ["bedrock.amazonaws.com"]
}
}
aws:CalledViaLast = bedrock.amazonaws.com の条件を付与することで、Bedrock 経由の呼び出しのみに権限を限定しています。
なお、aws:CalledViaLast は「このアクションを実行しているのがどの AWS サービスか」を条件にするキーになります。
今回のケースに当てはめると、呼び出しチェーンは以下の流れになっています:
Lambda ロール → Bedrock → AWS Marketplace (ViewSubscriptions, Subscribe)
aws:CalledViaLast = bedrock.amazonaws.com を条件に付けることで、Marketplace のアクションは Bedrock が代わりに呼び出す場合にのみ許可され、Lambda ロールが Marketplace を直接呼び出すことは防ぐようなイメージになります。
AWS global condition context keys - Properties of the request
aws:CalledVia
- Use this key to compare the services in the policy with the services that made requests on behalf of the IAM principal (user or role). When a principal makes a request to an AWS service, that service might use the principal's credentials to make subsequent requests to other services. When the request is made using forward access sessions (FAS), this key is set with the value of the service principal. The aws:CalledVia key contains an ordered list of each service in the chain that made requests on the principal's behalf.
無事、AIによる要約ができるようになりました。

今回の事象を通じて、Japan cross-region inference profile を使う際はルーティング対象の全リージョンで Marketplace モデルの初回実行を済ませておいた方が良いかもしれません。
具体的にはルーティング先のリージョンをすべて事前に確認し、各リージョンの Playground でモデルを一度実行しておくのがよいかと思います。
| 確認事項 | 理由 |
|---|---|
| 使用する inference profile のルーティング先リージョンをすべて確認 | 初回実行が未実施のリージョンにルーティングされると 403 になる |
| 各リージョンの Playground などでモデルを一度実行しておく | Marketplace モデルはこの初回実行でアカウント全体に有効化される |
| Lambda IAM ロールに Marketplace 権限を付与 | Bedrock が FAS 経由で Marketplace 処理を代行できるようになり、新リージョン追加時も手動実行なしで通る可能性がある |
なお、Japan cross-region inference profile のルーティング先リージョンは AWS ドキュメント で確認できます。
今回の問題は、cross-region inference profile が複数リージョンに動的ルーティングする仕様を把握しておらず、大阪リージョンで Marketplace モデルの初回実行が未実施のまま本番稼働していたことが原因のようでした。
「成功したり失敗したりする」という断続的な挙動は、2 リージョン間でルーティングされているものの、片方のリージョンだけ失敗しているというシグナルとして読み解けると思います。
Lambda の IAM ロールへの Marketplace 権限追加は予防策として有効ですが、根本的には inference profile 導入時にルーティング先の全リージョンで初回実行を済ませておくのが動作確認も兼ねて一番シンプルな解決策かと思います。
論文PDF処理パイプラインの最終段階について解説。両経路の結果をまとめるfinalizer Lambdaが、comparison.jsonを生成してDynamoDBを更新する仕組みと、経路ごとの状態管理、レビュー要否の判定ロジックを説明しています。
AWS AIPの知見を活かし、論文PDFを構造化JSONに変換するパイプラインを構築。S3、Lambda、Step Functions、Textract、Bedrockを組み合わせ、2つの抽出経路で日本語・英語PDFを処理し、メタデータ付きの構造化データをRAGのソースとして活用する仕組みを実装。
論文PDFを構造化JSONに変換するパイプラインの経路B(画像をBedrockに直接読ませる方式)について、Step Functionsでページを並列処理し、各Lambdaがページ画像からモデルで構造化データを抽出、S3に保存、最後にfinalizerで結合・正規化・検証する流れを詳説。
Grafana × Loki を使用してログ検索・表示方法を解説。LogQL でのログ検索、ログ詳細表示、Trace との相互遷移機能を紹介。Log と Trace を組み合わせることで問題切り分けが効率化される利点を説明。
AWS Lambdaのエラー通知をSlackに送信する際の設計ポイントを解説。ログ永続化、Subscription Filter上限対策、コスト最適化、通知遅延を考慮し、CloudWatch Logs→Lambda→Slack通知とFirehose→S3保存の構成を採用した実装例を紹介。