Skip to content

Invalid JSON-RPC envelope errors are not correlated with the original request id #2848

@cclabadmin

Description

@cclabadmin

Initial Checks

Description

After a normal initialization flow, several id-bearing JSON-RPC messages that are syntactically valid JSON but invalid JSON-RPC request envelopes are not correlated back to the original request id.

This is not meant to require implementations to recover an id after every low-level parse/deserialization failure. The narrower concern is that these payloads are parsed far enough to produce request-specific validation errors, while the original top-level id is still present in the payload. Preserving that id where feasible would make the error response easier for clients to correlate.

The tested inputs were:

Case Request Validation detail
wrong jsonrpc version {"jsonrpc":"1.0","id":3,"method":"ping","params":{}} JSONRPCRequest.jsonrpc: value should be "2.0"
missing jsonrpc field {"id":4,"method":"ping","params":{}} JSONRPCRequest.jsonrpc: field required
method as number {"jsonrpc":"2.0","id":8,"method":12345,"params":{}} JSONRPCRequest.method: input should be a valid string

For all three envelope-invalid inputs, I would expect -32600 Invalid Request or -32602 error response that can be correlated to the original request where possible.

Observed behavior was consistent by transport:

  • stdio: The server emits a notifications/message log notification with level:"error" and data:"Internal Server Error", but no JSON-RPC error response is sent for the original request id. A follow-up ping succeeds.
  • Streamable HTTP: The server returns HTTP 400 with a JSON-RPC error response using id:"server-error" and code:-32602, rather than the original request id. A follow-up ping succeeds over SSE.

Example Code

"""
With a Python SDK MCP server running over stdio or Streamable HTTP,
complete a normal initialization flow, then send these requests in isolation.
"""

requests = [
    # Wrong JSON-RPC version: valid JSON, invalid JSON-RPC envelope.
    {"jsonrpc": "1.0", "id": 3, "method": "ping", "params": {}},

    # Missing jsonrpc field: valid JSON, invalid JSON-RPC envelope.
    {"id": 4, "method": "ping", "params": {}},

    # method is not a string: valid JSON, invalid JSON-RPC envelope.
    {"jsonrpc": "2.0", "id": 8, "method": 12345, "params": {}},
]

Python & MCP Python SDK

* Python: `3.12.3`
* MCP Python SDK stable release: `v1.27.2` (`62137874ff26dd74d2fea80ff528a7fd9ca7a5e7`)
* Transports: stdio and Streamable HTTP

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions