Skip to content

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:

json
{
  "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:

text
`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:

text
"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. Raise max_tokens within the cap, or lower effort so less of the budget goes to thinking.
  • "prompt is too long" — the input exceeds the context window. See prompt is too long.
  • A Python ValueError before 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):

ModelAPI IDContext windowMax output (max_tokens)
Claude Opus 5.5claude-opus-5-51M128K
Claude Sonnet 5.5claude-sonnet-5-51M128K
Claude Haiku 5.5claude-haiku-5-51M128K
Claude Opus 4.5claude-opus-4-5-20251101200K64K
Claude Sonnet 4.5claude-sonnet-4-5-20250929200K64K
Claude Haiku 4.5claude-haiku-4-5-20251001200K64K

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-24 beta header.
  • Minimum. max_tokens can be 0, which populates the prompt cache without generating a response. That does not combine with manual extended thinking, because the budget must be less than max_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:

bash
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 ​

  1. A value copied between models. 128000 works on Opus 5.5 and fails on Haiku 4.5, which tops out at 64K.
  2. Off-by-one "maximum" settings. Several public reports show 128001 > 128000 — the cap itself is allowed, one more is not.
  3. Client defaults. Tools set max_tokens for you. Claude Code reads CLAUDE_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.
  4. Budget not below max_tokens. With manual extended thinking, thinking tokens count toward max_tokens, so the budget must leave room for the answer.
  5. Old thinking config on a new model. Code written for Claude Sonnet 4.6 or earlier sends budget_tokens to a 4.7+ model that rejects extended thinking.

Fix 1: Clamp max_tokens Per Model ​

Keep one source of truth and clamp every request:

python
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:

python
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:

ModelAcceptedRejected with 400
Claude Opus 5.5adaptive (always on)"enabled" (budget), "disabled"
Claude Sonnet 5.5adaptive, "between_tools""enabled", "disabled"
Claude Haiku 5.5adaptive; "disabled" at effort high or below"enabled"
Claude Opus 4.6 / Sonnet 4.6adaptive; "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:

json
{
  "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:

python
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_p and top_k are removed, and sending any of them returns a 400 on every model.
  • Forced tool use. tool_choice of {"type": "any"} or a named tool returns a 400 on Claude Opus 5.5 and Sonnet 5.5; auto and none are accepted.
  • Effort with thinking off. On Sonnet 5.5 with between_tools, or Haiku 5.5 with disabled, effort xhigh or max returns a 400, and so does a per-message effort that differs from the level in effect.
  • between_tools elsewhere. 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-5 and claude-haiku-5-5 (also callable as dotted aliases like claude-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_tokens to a 5.5 model and you get the "thinking.type.enabled" is not supported error; use adaptive thinking and effort instead. In Claude Code (ANTHROPIC_BASE_URL=https://byesu.com, without /v1), keep CLAUDE_CODE_MAX_OUTPUT_TOKENS at 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.

Got a problem? Contact support or join our group.