Skip to content

Streamable HTTP accepts unsupported or malformed MCP-Protocol-Version headers #957

@cclabadmin

Description

@cclabadmin

Bug description

After a normal Streamable HTTP initialization flow, the server transport accepts requests with an unsupported or malformed MCP-Protocol-Version header and dispatches them normally with HTTP 200. The MCP Streamable HTTP specification for 2025-11-25 requires that if a server receives a request with an invalid or unsupported MCP-Protocol-Version, it MUST respond with HTTP 400 Bad Request.

This is a server-side validation issue. It is separate from client-side fixes that make the Java SDK client send the negotiated protocol version correctly.

Environment

  • Java SDK: reproduced with v1.1.2
  • Also reproduced with a main snapshot from 2026-05-11 (87e2c7d4dec60dc98a981ff24fedc2afc960de72)
  • Transport: Streamable HTTP server
  • Java: Java 17 target
  • Spring MCP integration: not required for reproduction
  • Vector store: not used

Steps to reproduce

  1. Start a Java SDK Streamable HTTP server.
  2. Complete a normal initialize followed by notifications/initialized flow.
  3. Send a valid JSON-RPC request, such as tools/list, with MCP-Protocol-Version set to a well-formed but unsupported value such as 1900-01-01.
  4. Repeat with a malformed value such as not-a-version.
  5. Observe that the request is dispatched and returns HTTP 200.

Expected behavior

The server should reject the request before dispatching it:

HTTP/1.1 400 Bad Request

Minimal Complete Reproducible example

Set ENDPOINT to a Java SDK Streamable HTTP endpoint:

ENDPOINT=http://127.0.0.1:8080/mcp

Initialize and copy the returned Mcp-Session-Id header into SID:

curl -i -sS --http1.1 -X POST "$ENDPOINT" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  --data '{"jsonrpc":"2.0","id":"init-1","method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"version-header-repro","version":"0.1.0"}}}'

Send the initialized notification:

curl -i -sS --http1.1 -X POST "$ENDPOINT" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  -H "Mcp-Session-Id: $SID" \
  --data '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}'

Send an otherwise valid request with an unsupported protocol version:

curl -i -sS --http1.1 -X POST "$ENDPOINT" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 1900-01-01' \
  -H "Mcp-Session-Id: $SID" \
  --data '{"jsonrpc":"2.0","id":"bad-version-1","method":"tools/list","params":{}}'

Observed response:

HTTP/1.1 200 OK

{"jsonrpc":"2.0","result":{"tools":[...]},"id":"bad-version-1"}

The same behavior is observed with a malformed header value:

curl -i -sS --http1.1 -X POST "$ENDPOINT" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: not-a-version' \
  -H "Mcp-Session-Id: $SID" \
  --data '{"jsonrpc":"2.0","id":"bad-version-2","method":"tools/list","params":{}}'

Observed response:

HTTP/1.1 200 OK

{"jsonrpc":"2.0","result":{...},"id":"bad-version-2"}

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions