DEV Community

Multigrid
Multigrid

Posted on • Originally published at multigrid.ai

Fixing AccessDeniedException When You Request Bedrock Model Access

You have bedrock:InvokeModel in your policy, the model id is right, the Region is right, and the call returns a 403 with AccessDeniedException. Almost every guide you will find tells you to go to the Model access page and request access. That page works differently now, and following those instructions usually leaves you exactly where you started.

The error

botocore.errorfactory.AccessDeniedException: An error occurred
(AccessDeniedException) when calling the Converse operation: You don't have
access to the model with the specified model ID.
Enter fullscreen mode Exit fullscreen mode

HTTP 403. AWS’s troubleshooting page gives the generic cause — insufficient permissions for the requested action — which is true and not useful, because the permission you are missing is usually not a bedrock: one at all. There are three specific causes, and they are distinguishable.

What changed, and why old guides mislead

Bedrock used to hold third-party models behind a per-Region request that an account administrator approved in the console, with statuses like “Available to request” and “Access granted”. AWS’s model access documentation now opens by stating that access to all Amazon Bedrock foundation models is enabled by default with the correct AWS Marketplace permissions, in all commercial Regions.

What actually happens on a first invocation is that Bedrock initiates an AWS Marketplace subscription in the background. AWS documents a setup period of up to 15 minutes during which calls may succeed temporarily while the subscription finalises, and that after you grant missing permissions it can take up to 2 minutes for the subscription to complete — during which calls continue to return AccessDeniedException.

That is why the symptom is confusing. Access is not a switch somebody flips; it is a subscription that either completed, is in flight, or failed for a reason that has nothing to do with Bedrock’s own IAM actions.

This is the volatile part of the page. AWS has changed the model access model more than once, and GovCloud still uses a manual Model access pane in the console under Bedrock configurations. Check AWS’s model access page for the behaviour current when you read this; the description here is as documented in August 2026.

Cause one: Marketplace permissions

The subscription needs Marketplace actions on the calling identity. AWS lists three: aws-marketplace:Subscribe, aws-marketplace:Unsubscribe and aws-marketplace:ViewSubscriptions. These are not in a bedrock:* wildcard, which is exactly why a policy that looks complete fails.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "aws-marketplace:Subscribe",
        "aws-marketplace:Unsubscribe",
        "aws-marketplace:ViewSubscriptions"
      ],
      "Resource": "*"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Two consequences worth knowing. First, these permissions are only needed the first time a model is used in an account — once it is enabled, ordinary callers invoke it without them, so a Lambda execution role does not need Marketplace rights forever. Second, if the identity that first calls the model cannot assume them, somebody who can must trigger the enablement once, as a one-time step.

A related trap: an organisation that denies aws-marketplace:Subscribe to block models has not blocked them. AWS notes that denying Subscribe alone will not stop the first invocation, because Bedrock auto-initiates the subscription; blocking access properly means denying bedrock:InvokeModel on the foundation-model ARN via SCP or IAM. If you are on the receiving end of a 403 that survives every permission you add, look for that deny.

Also check the billing side. AWS lists a valid payment method for Marketplace purchases as a prerequisite, and documents a distinct failure — “AWS Marketplace Agreement Failed within 15 minutes”, also a 403 — whose common causes are an invalid payment instrument or a restricted geolocation. A brand-new account with no card on file produces a Bedrock permission error, which is not where anyone looks.

Cause two: the Anthropic use-case form

Anthropic models on Bedrock require a first-time-use form to be submitted before any invocation. If it has not been, AWS returns a distinct error code, FTUFormNotFilled, documented as HTTP 404 with the cause “Model use case details have not been submitted for this account”.

You do not need the console for this. The API is PutUseCaseForModelAccess, and it takes the form as base64-encoded JSON:

FORM=$(printf '%s' '{
  "companyName": "Acme Ltd",
  "companyWebsite": "https://acme.example",
  "intendedUsers": "1",
  "industryOption": "Software",
  "otherIndustryOption": "",
  "useCases": "Internal support-ticket summarisation for our own staff."
}' | base64 -w0)

aws bedrock put-use-case-for-model-access --form-data "$FORM"
Enter fullscreen mode Exit fullscreen mode

intendedUsers is 0 for internal, 1 for external, 2 for both. useCases allows up to 8192 characters; the name and website fields up to 128 each. AWS states access is granted immediately after the details are submitted successfully, that the form is required once per account or once at an organisation’s management account with the submission inherited by member accounts, and that opt-in Regions need it again. The CLI commands in this flow need AWS CLI v2.27.42 or later.

If you are an individual rather than a company, AWS explicitly allows a personal portfolio, GitHub profile or project URL in place of a company website — the field being required is not a reason to invent a domain.

Checking access without invoking

The third cause is timing, and the way to rule it out is to stop probing with real inference. GetFoundationModelAvailability answers the question directly:

  1. Run aws bedrock get-foundation-model-availability --model-id anthropic.claude-sonnet-4-5-20250929-v1:0 in the Region you are calling from.
  2. Read agreementAvailability.status. AWS documents AVAILABLE when access exists and NOT_AVAILABLE when it does not. The response also carries authorizationStatus, entitlementAvailability and regionAvailability, which separate “you are not allowed” from “this model is not offered here”.
  3. If it says NOT_AVAILABLE, run aws bedrock list-foundation-model-agreement-offers --model-id ... to get an offerToken, then aws bedrock create-foundation-model-agreement --model-id ... --offer-token .... That is the console button, as an API call.
  4. If it says AVAILABLE and inference still fails, the problem is an ordinary IAM or SCP deny on bedrock:InvokeModel — and if the caller is a Lambda function, check the execution role rather than your own credentials. See the Lambda-specific version of this failure.

One structural point that catches people who think they have already solved this: subscription state is per account, not per Region, and AWS notes that a model subscribed in one Region becomes available to request in every Region where it is offered. Model availability is very much per Region. So “it works in us-east-1 and 403s in eu-west-1” is not a subscription problem — it is either regionAvailability, or a Region-scoped policy, and a least-privilege Bedrock policy written against one Region is a common source of the second.

Related

Top comments (0)