BerriAI/litellm · error · Exception

Bedrock guardrail failed: {e}

Error message

Bedrock guardrail failed: {e}

What it means

This is a catch-all wrapper raised by the Bedrock guardrail hook in litellm's proxy when ANY unexpected exception occurs while applying the guardrail (i.e., calling bedrock:ApplyGuardrail and processing its response). HTTPException and ModifyResponseException are deliberately re-raised untouched, so this generic Exception only fires for operational failures: AWS credential errors, AccessDeniedException on the guardrail ARN, ThrottlingException, guardrail-not-found in the configured region, network failures, or bugs parsing the Bedrock response. The original exception text is preserved in the message but the exception type is flattened to a plain Exception.

Source

Thrown at litellm/proxy/guardrails/guardrail_hooks/bedrock_guardrails.py:3093

                scanned_role_subset=scanned_role_subset,
            )

            verbose_proxy_logger.debug("Bedrock Guardrail: Successfully applied guardrail")

            inputs["texts"] = masked_texts
            return inputs

        except (HTTPException, ModifyResponseException):
            # Let guardrail blocking exceptions propagate as-is so the proxy can
            # return the correct HTTP status (400 for HTTPException, 200 with the
            # block message for ModifyResponseException in disable_exception_on_block
            # mode). Without this, the generic except below wraps them into a plain
            # Exception, losing the semantics and preventing the proxy from
            # properly blocking the call.
            raise
        except Exception as e:
            verbose_proxy_logger.error("Bedrock Guardrail: Failed to apply guardrail: %s", str(e))
            raise Exception(f"Bedrock guardrail failed: {e}")

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Check the proxy logs for the preceding line 'Bedrock Guardrail: Failed to apply guardrail: <e>' — the original error (e.g., AccessDeniedException, ExpiredToken) tells you the real cause; fix that (credentials, IAM bedrock:ApplyGuardrail permission, guardrail_id/version, region).
  2. Verify the guardrail exists and is enabled in the region you configured: aws bedrock get-guardrail --guardrail-identifier <id> --guardrail-version <v> --region <region>.
  3. If the error is transient (ThrottlingException, timeouts), raise AWS retry capacity or attach multiple guardrail attempts via litellm's guardrail retry settings / circuit breaker config.
  4. If the failure persists and you want the request to proceed without scanning, remove/disable the guardrail for that deployment (guardrails: [] on the model or mode: passthrough off) rather than letting every call fail.
  5. Upgrade litellm to the latest patch if the inner exception indicates a parsing bug in the guardrail response handling.

Example fix

# config.yaml — before (guardrail missing region + wrong id)
guardrails:
  - guardrail_name: bedrock-pii
    litellm_params:
      guardrail: bedrock
      guardrail_id: arn:aws:bedrock:us-east-1:1234:guardrail/GRDMOCK
      guardrailVersion: DRAFT

# after — explicit region matching the guardrail, valid version
 guardrails:
  - guardrail_name: bedrock-pii
    litellm_params:
      guardrail: bedrock
      guardrail_id: arn:aws:bedrock:us-west-2:1234:guardrail/GRDMOCK
      guardrailVersion: "1"
      aws_region_name: us-west-2
Defensive patterns

Strategy: try-catch

Validate before calling

# Pre-flight the guardrail before attaching it to traffic
import boto3, os
client = boto3.client("bedrock-runtime", region_name=os.environ.get("AWS_REGION", "us-east-1"))
client.get_guardrail(guardrailIdentifier="<your-guardrail-id>")  # raises if missing/permissions bad
# ensure runtime credentials exist
assert client._request_signer._credentials is not None, "no AWS credentials"

Try / catch

try:
    resp = await litellm.acompletion(model="anthropic/claude-...", messages=msgs, guardrails=["bedrock-pii"])
except Exception as e:  # generic Exception is all this wrapper gives you
    if "Bedrock guardrail failed:" in str(e):
        inner = str(e).split("Bedrock guardrail failed:", 1)[1].strip()
        if "ThrottlingException" in inner or "Timeout" in inner:
            await asyncio.sleep(1); resp = await retry_call()
        elif "AccessDenied" in inner or "ExpiredToken" in inner:
            alert_ops(f"guardrail IAM/creds broken: {inner}")
        else:
            raise

Prevention

When it happens

Trigger: A request routes through a deployment with a bedrock guardrail attached (guardrails: [bedrock]) and the underlying boto3 ApplyGuardrail call fails: expired/missing AWS credentials, guardrail_id/guardrailVersion not present in the aws_region_name, IAM policy missing bedrock:ApplyGuardrail, throttling, or a response payload that violates the parsing code's expectations. Raised from async_apply_guardrail during pre_call/post_call hooks.

Common situations: Typical after adding a Bedrock guardrail entry to config.yaml with a typo'd guardrail_id, omitting aws_region_name (defaults to a region where the guardrail does not exist), running the proxy in an environment without AWS credentials (no AWS_PROFILE/instance role), or hitting AWS throttling under load. Also appears after litellm upgrades that change the expected ApplyGuardrail response shape.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/0bcf52a5ff64ff43. Report an issue: GitHub.