A Claude request returning HTTP 400 on AWS does not have one universal fix. Start with the error code, complete error message, and endpoint. A rejected request field needs a different correction from an invalid model identifier, a broken tool conversation, or a model’s data-retention requirement. Retrying the same request will not resolve those differences.
For Claude Code, CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 can help when a gateway rejects beta headers or beta-only fields. It does not repair every Bedrock ValidationException, and it does not simply turn off prompt caching. For an application calling AWS directly, first verify that the JSON matches the API you are actually using.
The steps below reflect official documentation checked September 21, 2026. The code is an illustrative diagnostic example; we did not run inference against an AWS account.
Find the useful part of the error
Capture the error before changing settings. Keep the AWS Region, model or inference-profile identifier, operation or endpoint, and request ID alongside the error code and message. For Claude Code, also record claude --version and whether the request goes directly to AWS or through a gateway. Redact credentials, prompts, and customer data before sharing logs.
HTTP 400 alone is a poor diagnosis. AWS lists signature, authorization, request-expiration, and validation failures among its 400 responses. The Converse API separately documents ValidationException as 400, AccessDeniedException as 403, and throttling as 429. Use the specific exception instead of assuming that every 400 is malformed JSON—or that a 400 rules out permissions. AWS API errors, Converse API reference.
There is also a quota exception: InvokeModel can return ServiceQuotaExceededException with HTTP 400. AWS says the request exceeds the account’s service quota and may be resubmitted later. Check the relevant quota and usage before choosing a retry strategy; this is different from resending an unchanged invalid payload. InvokeModel error reference.
| Error message or clue | First check | Useful next action |
|---|---|---|
The provided model identifier is invalid | Exact model/profile identifier and Region | Check the identifier against the resources available to this AWS account in that Region. |
Malformed input request, extraneous key, or a missing required field | Endpoint and request format | Compare the body with that operation’s documentation; remove fields from another API. |
Extra inputs are not permitted in Claude Code | Rejected field, client version, and gateway behavior | Check beta support and header forwarding before changing unrelated AWS settings. |
| Tool-use or thinking-block mismatch | Conversation immediately before the failed turn | Restore a valid earlier turn or test a fresh conversation. |
| Message names a thinking mode or token budget | Selected model and thinking configuration | Use the mode supported by that model and validate its budget rules. |
| Message explicitly mentions data retention | Effective account policy, Region, and model eligibility | Ask the AWS administrator to verify the allowed retention mode. |
ServiceQuotaExceededException from InvokeModel | Account service quota and usage | Address the quota condition and follow AWS guidance on later resubmission. |
This is a triage table, not a list of interchangeable fixes. AWS’s ValidationException troubleshooting guide also covers unsupported APIs, token limits, guardrail configuration, and some authorization failures. Follow a specific clue in the returned message before trying broader changes.
Match your payload to the endpoint
Bedrock offers more than one way to send Claude messages. Similar-looking API names do not make their request bodies interchangeable.
| Interface | Model selection | Message and generation fields | Version handling |
|---|---|---|---|
Native InvokeModel with Claude Messages | modelId in the AWS operation | Provider JSON body: messages, max_tokens, optional system; text blocks use type: "text" | Body includes anthropic_version: "bedrock-2023-05-31" |
Bedrock Converse | modelId in the AWS operation | messages with content such as {"text": "Hello"}; inferenceConfig.maxTokens; optional top-level system array | Do not copy the native Claude version field into Converse’s top level |
| AWS Anthropic-compatible Messages endpoint | model in the JSON body | Anthropic-compatible Messages request body | Uses the anthropic-version HTTP header |
| Third-party gateway | Defined by that gateway | Defined by its exposed API and forwarding behavior | Follow the gateway’s documentation and supported upstream features |
AWS documents the native Claude Messages body, the Converse request, and the Anthropic-compatible Messages endpoint separately. The compatible /anthropic/v1/messages route is documented for both bedrock-runtime and bedrock-mantle. Do not infer the payload format from the word “Bedrock” alone.
Common migration mistakes include sending max_tokens to Converse’s top level, sending inferenceConfig inside a native Claude body, or carrying older text-completion fields such as prompt and max_tokens_to_sample into a Messages request. For native Claude Messages, put instructions in the separate system field rather than inventing a system message role.

Use a minimal request to isolate the failure
For an application using Converse, the following example deliberately leaves out tools, images, guardrails, and optional model-specific parameters. Supply a model or inference-profile identifier valid for your account and Region. Running it makes an inference request and may incur usage charges.
pythonimport os import boto3 from botocore.exceptions import ClientError client = boto3.client( "bedrock-runtime", region_name=os.environ["AWS_REGION"], ) try: response = client.converse( modelId=os.environ["BEDROCK_MODEL_ID"], messages=[{ "role": "user", "content": [{"text": "Reply with OK."}], }], inferenceConfig={"maxTokens": 64}, ) print(response["output"]["message"]) except ClientError as exc: error = exc.response.get("Error", {}) metadata = exc.response.get("ResponseMetadata", {}) print({ "code": error.get("Code"), "message": error.get("Message"), "http_status": metadata.get("HTTPStatusCode"), "request_id": metadata.get("RequestId"), }) raise
This example requires boto3 and AWS credentials configured through your normal credential mechanism. It is intended for a model that supports Converse, not a Prompt management ARN with additional field restrictions.
If the minimal call succeeds, add your application’s system instructions, tools, conversation history, and optional features back one at a time. The first addition that causes the failure narrows the investigation. A successful basic text call does not establish that tool use, extended thinking, streaming, or your original transcript will work.
If your application uses native InvokeModel, keep that operation and test a minimal native body instead:
json{ "anthropic_version": "bedrock-2023-05-31", "max_tokens": 64, "messages": [ { "role": "user", "content": [{"type": "text", "text": "Reply with OK."}] } ] }
Serialize this JSON into the operation’s body, use contentType="application/json", and pass the model through modelId. Do not paste this body unchanged into Converse or the compatible Messages endpoint.
When the failure comes from Claude Code
Claude Code can send fields that depend on a particular client version, model capability, or beta feature. Its official request-error reference describes a gateway failure in which beta-only fields reach the upstream service but their anthropic-beta header does not.
Read the rejected field and any minimum-version message first. Check claude --version; if the error requires a newer client, use claude update or your managed installation’s update process. Updating the client cannot add a capability that the selected model or gateway does not support.
For an unsupported beta field, either correct header forwarding when the upstream supports that feature or try the documented fallback in a new shell-launched session:
bashCLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 claude
The current environment-variable documentation says this removes Anthropic-specific beta headers and beta tool-schema fields. Standard tool fields, including cache_control, remain. It also disables MCP tool search and loads tools upfront; managed settings can retain tool search on version 2.1.227 or later. Account for that behavior when comparing results.
If a clean session works but an existing conversation fails with a tool-use or thinking-block mismatch, use /rewind or press Esc twice to return to before the corrupted turn, as the Claude Code error guide recommends. Avoid manually deleting arbitrary transcript blocks: the relationships between tool calls and results matter.
Check model selection and thinking together
A valid model name in another environment is not proof that the same identifier works in your AWS Region. Confirm the actual model ID or inference-profile ID/ARN you are using. When AWS directs you to an inference profile, use the profile available for that account and Region; do not construct one by guessing a geographic prefix. The accepted identifier types are listed in the Converse reference.
For an “on-demand throughput isn’t supported” message, check the required inference profile. In Claude Code, /status helps confirm the active provider. Mantle uses its own anthropic.* model IDs; an Invoke inference-profile ID such as us.anthropic.* is not a Mantle model ID. A geographic-prefix preference in Claude Code also does not guarantee availability. See the current Claude Code Bedrock configuration guide before carrying identifiers between those connections.
Next, compare optional parameters with the selected model’s capabilities. A generic wrapper may carry settings forward when the model changes. An unsupported thinking mode can produce a 400 even when the message body otherwise looks correct.
AWS’s current extended-thinking documentation distinguishes adaptive thinking from older enabled/disabled configurations. It specifically lists models that reject the latter with a 400. For standard extended thinking, the thinking budget must be below max_tokens; interleaved thinking has an explicit exception. Apply the rule for the selected model and mode instead of universally disabling thinking or enforcing one budget formula.
For token-limit errors, inspect both input size and the requested output allowance. A short new question can still travel with a long conversation and extensive tool definitions. Reduce the relevant input or output allocation, then repeat the same diagnostic request. If the error specifically concerns assistant prefill, use the separate Claude prefill troubleshooting guide.
Treat retention errors as an account-policy question
When the message says the selected model requires a data-retention setting, rearranging JSON fields will not solve the underlying policy mismatch. Check the model, Region, and effective account configuration with the administrator responsible for AWS data handling.
As of September 21, 2026, AWS recommends aws_review for new configurations. Its documentation describes provider_data_share as a legacy value and states that content is not currently sent to model providers through that setting. Review remains within AWS; the documented period for the named Fable models is up to 30 days. Older posts describing this as automatic sharing with Anthropic do not reflect the current documentation. AWS data-retention controls.
These settings are regional. On bedrock-runtime, they apply at account scope rather than project scope. Explicitly approved zero-data-retention accounts may be allowed to use none for specific models; eligibility is not universal. Do not interpret an inherited/default value as an unconditional ZDR guarantee.
Before changing anything, establish which modes are allowed for the exact model and account, and whether the proposed setting meets your organization’s requirements. A blind account-wide opt-in is a poor troubleshooting shortcut.
Know when the fix is verified

Keep the endpoint, Region, and model constant while changing the suspected cause. Save the original error and the result of the corrected request. For a payload issue, verify the smallest failing feature and then the complete application request. For a history issue, check a valid conversation containing the tool interaction that previously failed. For a policy issue, confirm the effective setting with the administrator before testing again.
Stop repeating an unchanged validation failure. Backoff belongs to a different diagnosis, such as a transient failure or throttling; our retry versus fallback guide explains how to separate those cases. If the corrected request still fails, provide support with the request ID, timestamp, Region, model/profile identifier, operation, and a redacted reproduction. Those details make the next investigation more useful than another screenshot showing only “400.”



