You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Invalid UTF-8 in a request string returns 500 instead of 400 (Streamable HTTP) #1983
Description
If a POST body contains a JSON string value that is not valid UTF-8, the Streamable HTTP
handler returns 500 Internal Server Error. The JSON reader accepts the bytes, but ValidateProtocolVersionEnvelope later calls JsonValue.TryGetValue(out string), which throws InvalidOperationException: Cannot transcode invalid UTF-8 JSON text to UTF-16 string. HandlePostRequestAsync only catches JsonException, so the exception escapes.
This is related to #788 and was first noted by @rajashree23 in a comment on #1709. That PR
does not cover it. I found two paths:
_meta/io.modelcontextprotocol/protocolVersion on a 2026-07-28 request
(TryGetProtocolVersionMeta).
params.protocolVersion on an initialize request with an MCP-Protocol-Version header.
Steps to reproduce
POST a body where the protocol version string contains the byte 0xFF, for example ..."protocolVersion":"2025-11-25<0xFF>"..., with header MCP-Protocol-Version: 2025-11-25.
Expected
400 Bad Request with a JSON-RPC error that echoes the request id, consistent with the
other validation failures in this handler.
Actual
500 Internal Server Error. Reproduced on current main (deb6afa) and in v2.3.0.
Proposed fix
Treat the transcoding failure as a client error: catch it around the body validation in HandlePostRequestAsync and return 400 with a JSON-RPC error. I have two failing tests
in HttpHeaderConformanceTests that reproduce both paths.
Question for maintainers: should the error code be InvalidRequest (-32600), to match the
existing JsonException handling, or ParseError (-32700), because invalid UTF-8 is not
valid JSON text under RFC 8259?
Activity
skulkarniaugeomarketing commentedon Nov 1, 2026
Posted from the wrong account by mistake. Closing as a duplicate of #1984, which has the same content.