Claude API 400 max_tokens Too Large: Limits and Fixes
A request to /v1/messages fails with HTTP 400 invalid_request_error because of max_tokens — either it is above what the model can generate, or it conflicts with your thinking configuration. These are pure parameter validation errors: nothing ran, and the fix is a number or a field in your request body.
Quick answer
max_tokens cannot exceed the model's maximum output. On Anthropic's current models — Claude Opus 5.5, Sonnet 5.5 and Haiku 5.5 — that is 128K tokens on the synchronous Messages API; Claude Opus 4.5, Sonnet 4.5 and Haiku 4.5 allow 64K. Clamp the value per model. If you use manual extended thinking (thinking.type: "enabled"), budget_tokens must be at least 1,024 and less than max_tokens. On Claude 4.7 and later models, extended thinking is not accepted at all: remove budget_tokens, use thinking: {"type": "adaptive"}, and control depth with output_config.effort.
Symptoms and What the Error Means
Anthropic's docs state that max_tokens has model-specific maximums but do not publish the error text. Public error reports show this format — here a real example sent to a model with a 128K output cap:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "max_tokens: 250001 > 128000, which is the maximum allowed number of output tokens for claude-opus-4-6"
}
}The thinking-budget variant, also as publicly reported:
`max_tokens` must be greater than `thinking.budget_tokens`.And on Claude 4.7 and later models, sending a budget at all returns this 400, quoted from Anthropic's errors page:
"thinking.type.enabled" is not supported for this model. Use "thinking.type.adaptive" and "output_config.effort" to control thinking behavior.Neighbors that look similar but are not this error:
stop_reason: "max_tokens"in a successful response — the answer hit your ceiling and was truncated. Raisemax_tokenswithin the cap, or lowereffortso less of the budget goes to thinking.- "prompt is too long" — the input exceeds the context window. See prompt is too long.
- A Python
ValueErrorbefore any request is sent — the SDK refusing a long non-streaming call, not the API. See Anthropic API timeout.
Output Limits by Model
From Anthropic's models overview (synchronous Messages API):
| Model | API ID | Context window | Max output (max_tokens) |
|---|---|---|---|
| Claude Opus 5.5 | claude-opus-5-5 | 1M | 128K |
| Claude Sonnet 5.5 | claude-sonnet-5-5 | 1M | 128K |
| Claude Haiku 5.5 | claude-haiku-5-5 | 1M | 128K |
| Claude Opus 4.5 | claude-opus-4-5-20251101 | 200K | 64K |
| Claude Sonnet 4.5 | claude-sonnet-4-5-20250929 | 200K | 64K |
| Claude Haiku 4.5 | claude-haiku-4-5-20251001 | 200K | 64K |
Two exceptions to know about:
- Batch API. On the Message Batches API, Claude Opus 5.5, Sonnet 5.5, Haiku 5.5 and several other current models support up to 300K output tokens with the
output-300k-2026-03-24beta header. - Minimum.
max_tokenscan be0, which populates the prompt cache without generating a response. That does not combine with manual extended thinking, because the budget must be less thanmax_tokens.
Rather than hard-coding the table, read the limits from the source. Anthropic's Models API returns max_input_tokens and max_tokens for every model:
curl -s https://api.anthropic.com/v1/models \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
| jq '.data[] | {id, max_input_tokens, max_tokens}'Why It Happens
- A value copied between models.
128000works on Opus 5.5 and fails on Haiku 4.5, which tops out at 64K. - Off-by-one "maximum" settings. Several public reports show
128001 > 128000— the cap itself is allowed, one more is not. - Client defaults. Tools set
max_tokensfor you. Claude Code readsCLAUDE_CODE_MAX_OUTPUT_TOKENS; per its docs it lowers a value above a known model's cap to the cap, and for a model ID it can't resolve it defaults to 32000 with a cap of 128000. - Budget not below
max_tokens. With manual extended thinking, thinking tokens count towardmax_tokens, so the budget must leave room for the answer. - Old thinking config on a new model. Code written for Claude Sonnet 4.6 or earlier sends
budget_tokensto a 4.7+ model that rejects extended thinking.
Fix 1: Clamp max_tokens Per Model
Keep one source of truth and clamp every request:
MAX_OUTPUT = {
"claude-opus-5-5": 128_000,
"claude-sonnet-5-5": 128_000,
"claude-haiku-5-5": 128_000,
"claude-haiku-4-5-20251001": 64_000,
}
def safe_max_tokens(model: str, wanted: int) -> int:
cap = MAX_OUTPUT.get(model, 32_000) # conservative default for unknown IDs
return max(1, min(wanted, cap))Large values have a second constraint: duration. Anthropic recommends streaming or the Batch API for long requests, and its own sample code notes that the Python SDK requires streaming for max_tokens above about 21K. Pair a big ceiling with streaming:
import anthropic
client = anthropic.Anthropic()
model = "claude-sonnet-5-5"
with client.messages.stream(
model=model,
max_tokens=safe_max_tokens(model, 64_000),
messages=[{"role": "user", "content": "Write the full migration guide."}],
) as stream:
message = stream.get_final_message()
print(message.stop_reason, message.usage.output_tokens)max_tokens is a ceiling, not a target: the model may stop well before it, and you are billed for tokens actually generated. If long streams break midway, see streaming connection dropped.
Fix 2: Use the Right Thinking Configuration for the Model
Thinking errors depend on which model you call, so check Anthropic's thinking troubleshooting table before you change parameters. The models most people call today behave like this:
| Model | Accepted | Rejected with 400 |
|---|---|---|
| Claude Opus 5.5 | adaptive (always on) | "enabled" (budget), "disabled" |
| Claude Sonnet 5.5 | adaptive, "between_tools" | "enabled", "disabled" |
| Claude Haiku 5.5 | adaptive; "disabled" at effort high or below | "enabled" |
| Claude Opus 4.6 / Sonnet 4.6 | adaptive; "enabled" still works but is deprecated | — |
| Claude Opus 4.5 / Sonnet 4.5 / Haiku 4.5 | "enabled" with budget_tokens only | "adaptive" |
On Claude 4.7 and later, the fix is to drop the budget entirely:
{
"model": "claude-sonnet-5-5",
"max_tokens": 32000,
"thinking": {"type": "adaptive"},
"output_config": {"effort": "high"},
"messages": [{"role": "user", "content": "Plan the refactor step by step."}]
}Claude Opus 5.5 thinks without any configuration, so you can omit thinking there. Default effort is medium on Opus 5.5 and Haiku 5.5, and high on most other models that support effort.
On models that still use manual extended thinking, keep the budget inside the rules — at least 1,024 and below max_tokens:
def thinking_params(max_tokens: int, desired_budget: int) -> dict:
# Leave room for the visible answer; budget must stay below max_tokens
budget = min(desired_budget, max_tokens - 4_096)
if budget < 1_024:
raise ValueError("raise max_tokens: budget_tokens must be >= 1024 and < max_tokens")
return {"type": "enabled", "budget_tokens": budget}
params = dict(model="claude-haiku-4-5-20251001", max_tokens=16_000,
thinking=thinking_params(16_000, 10_000))The single documented exception is interleaved thinking in manual mode, where the budget spans every thinking block in the assistant turn and can exceed max_tokens.
Fix 3: Check the Other Parameter Validation 400s
If the clamp did not fix it, the 400 may come from a neighboring check. All of these are documented by Anthropic:
- Sampling parameters on the newest API version. With
anthropic-version: 2026-10-21,temperature,top_pandtop_kare removed, and sending any of them returns a 400 on every model. - Forced tool use.
tool_choiceof{"type": "any"}or a named tool returns a 400 on Claude Opus 5.5 and Sonnet 5.5;autoandnoneare accepted. - Effort with thinking off. On Sonnet 5.5 with
between_tools, or Haiku 5.5 withdisabled, effortxhighormaxreturns a 400, and so does a per-message effort that differs from the level in effect. between_toolselsewhere. Only Claude Sonnet 5.5 accepts it; other models return a 400.
Each message names the offending field, so read the error text before changing code.
If You're Calling Claude Through byesu
byesu is an AI API gateway with an OpenAI-compatible endpoint (https://byesu.com/v1) and an Anthropic-native endpoint (/v1/messages on the same host), billed pay-as-you-go with no subscription. Two points matter for this error:
- The ceiling belongs to the model, not the endpoint.
claude-opus-5-5,claude-sonnet-5-5andclaude-haiku-5-5(also callable as dotted aliases likeclaude-sonnet-5.5) carry Anthropic's 128K output cap whichever format you use, so clamp with the table in Fix 1. Because billing is per token actually generated, a sensible ceiling costs nothing extra; the real cost driver is how much the model writes and thinks. - Thinking follows the model's rules. Send
budget_tokensto a 5.5 model and you get the"thinking.type.enabled" is not supportederror; use adaptive thinking and effort instead. In Claude Code (ANTHROPIC_BASE_URL=https://byesu.com, without/v1), keepCLAUDE_CODE_MAX_OUTPUT_TOKENSat or below 128000.
To get started, create a token in the console and pick a model ID. Full setup: Quick Start.
FAQ
What is the max_tokens limit for Claude models?
It depends on the model. Claude Opus 5.5, Sonnet 5.5 and Haiku 5.5 allow up to 128K output tokens on the synchronous Messages API, while Claude Opus 4.5, Sonnet 4.5 and Haiku 4.5 allow 64K. On the Message Batches API, several current models, including the 5.5 models, support up to 300K with the output-300k-2026-03-24 beta header. Anthropic's Models API returns each model's max_tokens value.
Why do I get "max_tokens must be greater than thinking.budget_tokens"?
With manual extended thinking, thinking tokens count toward max_tokens, so budget_tokens must be at least 1,024 and less than max_tokens to leave room for the answer. Raise max_tokens or lower the budget. The only documented exception is interleaved thinking in manual mode, where the budget can exceed max_tokens.
Can I use budget_tokens with Claude Opus 5.5?
No. Claude 4.7 and later models, including Opus 5.5, Sonnet 5.5 and Haiku 5.5, reject thinking.type "enabled" with a 400. Use thinking type "adaptive" and set output_config.effort to control depth. On Opus 5.5 thinking is always on, so you can omit the thinking field entirely.
Does setting a high max_tokens cost more?
Not by itself. max_tokens is only a ceiling; you are billed for the tokens the model actually generates, including thinking tokens. A high value does make long, slow responses possible, so stream large requests — Anthropic recommends streaming or the Batch API for long-running calls, and the Python SDK refuses long non-streaming requests.
How is this different from stop_reason "max_tokens"?
The 400 error means the request was rejected before generation because max_tokens or the thinking settings were invalid. stop_reason "max_tokens" appears on a successful response that was cut off because it reached your ceiling. For the second case, raise max_tokens within the model's cap or lower effort so less of the budget goes to thinking.
