Gemini 2.5 Thinking Budget Exceeded — Fix (2026) | AI Error Hub
GeminiThinkingSeverity: MediumEmpty output

Gemini 2.5 Thinking Budget Exceeded / Response Empty

You get an empty response with reasoning tokens burned when Gemini 2.5's thinking_budget is too low for the task. Fix by increasing budget, using dynamic thinking (-1), disabling thinking on 2.5 Flash for simple tasks (0), or routing to Pro vs Flash based on complexity.

Detection: usage.thoughts_token_count hits budget, empty textCategory: ThinkingFeature: Gemini 2.5 series onlyLast tested: Nov 15, 2026
Quick Fix (TL;DR)

On Gemini 2.5 Pro, thinking is always ON with dynamic budget (128–32,768 tokens). On 2.5 Flash you can control it: thinking_budget=0 disables, -1 is dynamic, or a specific integer (up to 24,576). Empty response? Set budget to 8,192+ for complex tasks. Enable include_thoughts to inspect reasoning summaries.

The Symptoms You're Seeing

Response pattern
response.text = ""  # empty
response.candidates[0].finish_reason = "STOP"  # but no content

response.usage_metadata:
  prompt_token_count: 512
  candidates_token_count: 0        ← nothing visible
  thoughts_token_count: 24576       ← all budget used on thinking
  total_token_count: 25088

Model spent budget reasoning; had nothing left for output.

Or for wrong-model usage:
{
  "error": {
    "code": 400,
    "message": "Field 'thinking_config' is not supported for 
    model 'gemini-2.0-flash'.",
    "status": "INVALID_ARGUMENT"
  }
}

Thinking Support by Model

ModelThinkingBudget rangeDefault
gemini-2.5-proAlways on128 – 32,768Dynamic (-1)
gemini-2.5-flashConfigurable0 – 24,576Dynamic (-1)
gemini-2.5-flash-liteConfigurable0 – 24,5760 (off)
gemini-2.0-flashNot supportedN/AN/A
gemini-2.0-flash-thinking-expPreview onlyDeprecatedRetiring

What Actually Causes This Error

38%
Fixed budget too low for taskSet 4096 tokens, task needed 15K+ reasoning.
22%
thinking_config on unsupported modelPassing to 2.0 Flash or older; API rejects.
18%
Static budget on complex tasksDynamic (-1) would scale, but fixed cap blocks.
12%
Flash-Lite with thinking on for simple taskWastes tokens; should be 0 for classification.
10%
Not accounting for thinking in max_output_tokensBoth count against total generation budget.

Fixes That Work (Tested Nov 2026)

1Use Dynamic Thinking Budget

Python · let model decide
from google import genai from google.genai import types client = genai.Client() # Dynamic: model allocates based on task; safest default response = client.models.generate_content( model="gemini-2.5-flash", contents="Prove sqrt(2) is irrational, step by step.", config=types.GenerateContentConfig( thinking_config=types.ThinkingConfig( thinking_budget=-1, # -1 = dynamic include_thoughts=True # return reasoning summary ) ) ) # Inspect what happened print(f"Reasoning tokens: {response.usage_metadata.thoughts_token_count}") print(f"Output tokens: {response.usage_metadata.candidates_token_count}") # Extract reasoning + answer for part in response.candidates[0].content.parts: if part.thought: print("THOUGHT:", part.text) # reasoning summary else: print("ANSWER:", part.text) # final response

2Task-Based Budget Selection

Python · route by task complexity
def thinking_budget_for_task(task_type): return { # Off — no reasoning needed "classify": 0, "extract": 0, "summarize": 0, "translate": 0, # Small — quick sanity checking "format_data": 1024, "simple_qa": 2048, # Medium — real thinking "code_review": 4096, "debug_easy": 4096, "analysis": 8192, # Large — hard problems, dynamic recommended "math_proof": -1, "multi_step": -1, "planning": -1, "complex_debug": -1, }.get(task_type, -1) # dynamic default def generate_with_thinking(model, contents, task_type): budget = thinking_budget_for_task(task_type) return client.models.generate_content( model=model, contents=contents, config=types.GenerateContentConfig( thinking_config=types.ThinkingConfig(thinking_budget=budget) ) )
Cost impact of thinking tokens

Reasoning tokens billed at OUTPUT rate. On 2.5 Flash paid tier that's ~$0.30/M output. A hard math problem using 20K reasoning tokens costs about $0.006 just for thinking. Multiply by traffic — thinking budget = cost lever.

3Handle Empty Output from Overrun

Python · detect + retry with more budget
def generate_with_adaptive_budget(model, contents, start_budget=4096): """Retry with 2x budget if first attempt yields empty output.""" budget = start_budget for attempt in range(3): response = client.models.generate_content( model=model, contents=contents, config=types.GenerateContentConfig( thinking_config=types.ThinkingConfig(thinking_budget=budget) ) ) usage = response.usage_metadata has_output = (usage.candidates_token_count or 0) > 0 thought_ratio = ((usage.thoughts_token_count or 0) / max(budget, 1)) if has_output and response.text: return response # Empty output; check if budget was consumed if thought_ratio > 0.9: budget = min(budget * 2, 24576) print(f"Retry with budget={budget}") continue # Empty for other reason (safety, content_filter) break raise Exception("Empty output after adaptive retries")

Preventing This Error Going Forward

  • Default to dynamic budget (-1) unless cost-sensitive.
  • Set 0 for simple tasks on Flash / Flash-Lite. Saves tokens + latency.
  • Fixed budgets only when you can benchmark actual usage.
  • Track thoughts_token_count in logs. Tune from real data.
  • Enable include_thoughts in dev/staging. Debug reasoning drift.
  • Choose model by need for thinking. 2.5 Pro is always-on; use Flash for control.
SK
Tested by Sana K.
Researcher · AI Error Hub
Last verified: Nov 15, 2026 · SDK: google-genai 0.8+

Frequently Asked Questions

Yes — set include_thoughts=True and iterate candidates[0].content.parts; parts with thought=True contain reasoning summaries (not full trace). Full reasoning tokens counted but summarized for readability.

Yes — both thinking and visible output share the total generation budget. Set generous max_output_tokens (16K+) when thinking is high-budget, or specify thinking_budget explicitly and let visible output share the rest.

Yes — you can't disable it on 2.5 Pro. You can set thinking_budget to control the range (min 128, max 32,768). Off is not an option; that's the model design.

Usually no. Flash-Lite is optimized for high-throughput classification/extraction — thinking adds cost and latency without much quality gain on those tasks. Reserve thinking for Flash or Pro when reasoning matters.

Not always — dynamic scales to task complexity but caps at 24,576 (Flash) or 32,768 (Pro). Extremely hard problems may still consume the max. Monitor thoughts_token_count; if consistently near cap, tasks may need model upgrade or breaking into steps.