BerriAI/litellm · error · BedrockError

{err.response.text}

Error message

{err.response.text}

What it means

Raised when the synchronous Bedrock embedding HTTP call returns a non-2xx status (response.raise_for_status() throws httpx.HTTPStatusError). LiteLLM wraps it into BedrockError carrying the status code and the AWS response body as the message. Note the sibling handler maps timeouts to BedrockError 408.

Source

Thrown at litellm/llms/bedrock/embed/embedding.py:115

        api_base: str,
        headers: dict,
        data: dict,
    ) -> dict:
        if client is None or not isinstance(client, HTTPHandler):
            _params: Final = {}
            if timeout is not None:
                if isinstance(timeout, float) or isinstance(timeout, int):
                    timeout = httpx.Timeout(timeout)
                _params["timeout"] = timeout
            client = _get_httpx_client(_params)
        else:
            client = client
        try:
            response: Final = client.post(url=api_base, headers=headers, data=json.dumps(data))
            response.raise_for_status()
        except httpx.HTTPStatusError as err:
            error_code: Final = err.response.status_code
            raise BedrockError(status_code=error_code, message=err.response.text)
        except httpx.TimeoutException:
            raise BedrockError(status_code=408, message="Timeout error occurred.")

        return response.json()

    async def _make_async_call(
        self,
        client: AsyncHTTPHandler | None,
        timeout: float | httpx.Timeout | None,
        api_base: str,
        headers: dict,
        data: dict,
    ) -> dict:
        if client is None or not isinstance(client, AsyncHTTPHandler):
            _params: Final = {}
            if timeout is not None:
                if isinstance(timeout, float) or isinstance(timeout, int):
                    timeout = httpx.Timeout(timeout)

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Read e.status_code and e.message — the AWS body states the precise violation
  2. 403/404: verify modelId, region, and IAM bedrock:InvokeModel permissions
  3. 400: shrink or chunk input texts to the model's size limit
  4. 429: backoff and retry; consider batching controls in LiteLLM config

Example fix

# before
try:
    resp = litellm.embedding(model='bedrock/amazon.titan-embed-text-v2:0', input=['text'])
except Exception:
    raise

# after
from litellm.llms.bedrock.common_utils import BedrockError
try:
    resp = litellm.embedding(model='bedrock/amazon.titan-embed-text-v2:0', input=['text'])
except BedrockError as e:
    if e.status_code == 429:
        time.sleep(2 ** attempt); retry()
    else:
        raise
Defensive patterns

Strategy: retry

Try / catch

from litellm.llms.bedrock.common_utils import BedrockError

for attempt in range(5):
    try:
        resp = litellm.embedding(model="bedrock/amazon.titan-embed-text-v2:0", input=texts)
        break
    except BedrockError as e:
        if e.status_code == 429 and attempt < 4:
            time.sleep(2 ** attempt)
            continue
        if e.status_code == 400 and "inputText" in e.message:
            texts = [chunk_texts(t, 8192) for t in texts]; continue
        raise

Prevention

When it happens

Trigger: Invalid modelId for the region (404), access denied to bedrock:InvokeModel (403), payload validation errors (400, e.g. oversized inputText), or throttling (429) during litellm.embedding on bedrock models.

Common situations: Model access not enabled in the AWS account/region, IAM policy missing embedding-model permissions, inputs exceeding Titan/Nova per-request token limits, or rate limits under batch load.

Related errors


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