Every buffer, capped
The MCP Go SDK now rejects JSON at 1,000 levels of nesting, before the parser recurses
Version 1.8.0 bounds every decoding path that buffers input, and the two flags that undo it expire at 1.9.0.
| Path | The bound it gained |
|---|---|
| JSON decoding, all transports | rejected past 1,000 levels of nesting |
| SSE client and streamable client | MaxEventSize, bytes per single event |
| stdio transport | StdioTransport.MaxLineLength, per JSON-RPC frame |
| OAuth dynamic client registration | response read bounded to 1 MB |
The MCP Go SDK shipped v1.8.0 on 14 September, and its release notes state that “every decoding path that buffers incoming input is now bounded”.
The mechanism is ordering, not size. A nesting limit that fires after the parser has begun recursing does not help, so the check runs first: payloads are “rejected past 1000 levels of nesting, before the parser recurses”. Alongside it, both SSE readers cap bytes per event through MaxEventSize, the stdio transport caps a frame through StdioTransport.MaxLineLength, and an OAuth dynamic client registration response is read only to 1 MB.
Two of those three bounds are fields a server can raise. The nesting depth is not: the notes name MaxEventSize and StdioTransport.MaxLineLength as settings that take a value, against a flat 1,000 levels with no knob at all. That is the right call, because a tool argument legitimately nested a thousand deep is not a thing anyone has, and a limit nobody can raise is a limit an attacker cannot talk a careless operator into raising either.
Two behaviour changes come with an expiry date attached. Setting MCPGODEBUG to plaintextstatefulrejection=1 restores plain-text HTTP 400 responses in place of JSON-RPC errors, and blockingcancelnotify=1 restores synchronous cancellation delivery. The release schedules both for removal in v1.9.0, so a server leaning on either has one minor version to rewrite its error handling.
None of this is a protocol change. The notes say the release “adds no new protocol revision” and that 2026-07-28 remains the newest version the SDK negotiates, which makes this the transport learning to distrust its own input rather than the specification learning anything.
What it changes Upgrade, then check whether your clients parse plain-text 400s: that behaviour now needs an MCPGODEBUG flag and the flag dies at v1.9.0. If you generate deeply nested tool arguments, measure the depth before you upgrade rather than after.
Primary source read