API 400: cache_control TTL ordering violation in long sessions with many MCP tools
Resolved 💬 3 comments Opened Mar 27, 2026 by dirkenglund Closed Mar 30, 2026
Bug
Long Claude Code sessions with many MCP tools (40+) eventually hit this API error:
API Error: 400
{"type":"error","error":{"type":"invalid_request_error","message":"messages.1040.content.3.cache_control.ttl: a ttl='1h' cache_control block must not come after a ttl='5m' cache_control block. Note that blocks are processed in the following order: `tools`, `system`, `messages`."}}
Reproduction
- Start Claude Code with 10+ MCP servers (40+ tools total)
- Have a long conversation (1000+ message turns)
- Eventually the prompt assembly places a
ttl='1h'block after attl='5m'block
Environment
- Claude Code v2.1.83
- Opus 4.6 (1M context)
- macOS Darwin 24.6.0
- 10+ MCP servers active (neo4j, graphiti, lean-lsp, axiomatic, playwright, github, etc.)
Analysis
The Anthropic API requires cache_control TTL blocks to be non-increasing order (longer durations first). Claude Code's internal prompt assembly violates this constraint when:
- Tools (from MCP servers) are tagged with one TTL
- System instructions are tagged with another TTL
- Earlier messages in the conversation have a different TTL
The ordering tools → system → messages means if tools get ttl='5m' and system gets ttl='1h', it violates the monotonic constraint.
Impact
- Session becomes unusable after the error
- Only workaround is
/clearto reset conversation - Particularly affects power users with many MCP servers and long sessions
Expected behavior
Claude Code should ensure TTL blocks are assembled in non-increasing order, or use a consistent TTL across all cached blocks.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗