BerriAI/litellm · critical · PermissionDeniedError

BedrockException PermissionDeniedError - {error_str}

Error message

BedrockException PermissionDeniedError - {error_str}

What it means

Bedrock-specific: PermissionDeniedError raised when the AWS error text contains 'AccessDeniedException'. Credentials are valid, but the identity is not allowed to perform this Bedrock action — most often bedrock:InvokeModel or bedrock:InvokeModelWithResponseStream for the requested model ARN.

Source

Thrown at litellm/litellm_core_utils/exception_mapping_utils.py:869

    elif "A conversation must start with a user message." in error_str:
        raise BadRequestError(
            message=f"BedrockException - {error_str}\n. Pass in default user message via `completion(..,user_continue_message=)` or enable `litellm.modify_params=True`.\nFor Proxy: do via `litellm_settings::modify_params: True` or user_continue_message under `litellm_params`",
            model=model,
            llm_provider="bedrock",
            response=getattr(original_exception, "response", None),
        )
    elif (
        "Unable to locate credentials" in error_str
        or "The security token included in the request is invalid" in error_str
    ):
        raise AuthenticationError(
            message=f"BedrockException Invalid Authentication - {error_str}",
            model=model,
            llm_provider="bedrock",
            response=getattr(original_exception, "response", None),
        )
    elif "AccessDeniedException" in error_str:
        raise PermissionDeniedError(
            message=f"BedrockException PermissionDeniedError - {error_str}",
            model=model,
            llm_provider="bedrock",
            response=getattr(original_exception, "response", None),
        )
    elif "throttlingException" in error_str or "ThrottlingException" in error_str:
        raise RateLimitError(
            message=f"BedrockException: Rate Limit Error - {error_str}",
            model=model,
            llm_provider="bedrock",
            response=getattr(original_exception, "response", None),
        )
    elif "Connect timeout on endpoint URL" in error_str or "timed out" in error_str:
        raise Timeout(
            message=f"BedrockException: Timeout Error - {error_str}",
            model=model,
            llm_provider="bedrock",
        )

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. In the Bedrock console, open Model access and request/enable access for the model, then wait for approval.
  2. Attach/extend an IAM policy allowing bedrock:InvokeModel (and InvokeModelWithResponseStream if streaming) on the model ARN or '*'.
  3. Verify the model id's region matches AWS_REGION — model ARNs are region-scoped.
  4. Test with the AWS CLI (aws bedrock invoke-model ...) to separate IAM issues from litellm config.

Example fix

# before
# IAM policy only grants bedrock:ListFoundationModels
resp = litellm.completion(model="bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0", messages=msgs)

# after
# add to the caller's IAM policy:
# {
#   "Effect": "Allow",
#   "Action": ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"],
#   "Resource": "arn:aws:bedrock:*::foundation-model/anthropic.claude-3-5-sonnet-*"
# }
resp = litellm.completion(model="bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0", messages=msgs)
Defensive patterns

Strategy: validation

Validate before calling

import boto3

def can_invoke_bedrock_model(model_id: str, region: str) -> bool:
    """Cheap probe: attempt a 1-token invocation to surface IAM/access issues early."n    try:
        boto3.client("bedrock-runtime", region_name=region).invoke_model(
            modelId=model_id,
            body=b'{"prompt": "hi", "maxTokenCount": 1}',
            contentType="application/json", accept="application/json",
        )
        return True
    except Exception as e:
        return "AccessDeniedException" not in str(e)

Type guard

import litellm

def is_bedrock_permission_error(e: BaseException) -> bool:
    return isinstance(e, litellm.PermissionDeniedError) and getattr(e, "llm_provider", "") == "bedrock"

Try / catch

try:
    resp = litellm.completion(model="bedrock/...", messages=msgs)
except litellm.PermissionDeniedError:
    raise RuntimeError("enable model access in Bedrock console and grant bedrock:InvokeModel in IAM")

Prevention

When it happens

Trigger: IAM policy lacks bedrock:InvokeModel on the model ARN, or the model has not been enabled in Bedrock model access settings; also cross-region calls where foundation model ARNs are region-specific.

Common situations: Fresh AWS accounts that never requested model access in the Bedrock console, IAM users/roles with broad policies missing bedrock actions, ARN typos (wrong region prefix), or scoped-down policies that list specific model ARNs and omit the one being called.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/0ae2ccdcd69ae334. Report an issue: GitHub.