Skip to content

fix(streamable-http-server): map handler-generated HeaderMismatch to … - #1259

Open
voidstackloop wants to merge 1 commit into
modelcontextprotocol:mainfrom
voidstackloop:header-mismatch-status
Open

fix(streamable-http-server): map handler-generated HeaderMismatch to …#1259
voidstackloop wants to merge 1 commit into
modelcontextprotocol:mainfrom
voidstackloop:header-mismatch-status

Conversation

@voidstackloop

@voidstackloop voidstackloop commented Sep 11, 2026

Copy link
Copy Markdown

…HTTP 400

jsonrpc_http_status maps several protocol errors (unsupported protocol version, missing required client capability, invalid params) to HTTP 400 on the modern per-request Streamable HTTP path, but fell through to the default HTTP 200 for ErrorCode::HEADER_MISMATCH. When a ServerHandler returns Err(ErrorData::header_mismatch(...)), RMCP serialized the correct JSON-RPC -32020 error but sent it with HTTP 200.

The legacy/transport-generated header validation path (SEP-2243 Mcp-Method/Mcp-Name/Mcp-Param-* mismatches) was unaffected, since header_mismatch_jsonrpc_response constructs an HTTP 400 response directly rather than going through jsonrpc_http_status. Only handler-generated HeaderMismatch errors on the modern path hit the bug.

Add ErrorCode::HEADER_MISMATCH to the existing BAD_REQUEST match arm, matching the Streamable HTTP server-validation rules in the 2026-07-28 spec. Added unit tests covering the mapper directly (header-mismatch to 400, method-not-found to 404, an unmapped code defaulting to 200).

Closes #1225

Motivation and Context

How Has This Been Tested?

Breaking Changes

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

…HTTP 400

`jsonrpc_http_status` maps several protocol errors (unsupported protocol
version, missing required client capability, invalid params) to HTTP 400
on the modern per-request Streamable HTTP path, but fell through to the
default HTTP 200 for `ErrorCode::HEADER_MISMATCH`. When a `ServerHandler`
returns `Err(ErrorData::header_mismatch(...))`, RMCP serialized the
correct JSON-RPC -32020 error but sent it with HTTP 200.

The legacy/transport-generated header validation path (SEP-2243
Mcp-Method/Mcp-Name/Mcp-Param-* mismatches) was unaffected, since
`header_mismatch_jsonrpc_response` constructs an HTTP 400 response
directly rather than going through `jsonrpc_http_status`. Only
handler-generated HeaderMismatch errors on the modern path hit the bug.

Add `ErrorCode::HEADER_MISMATCH` to the existing `BAD_REQUEST` match arm,
matching the Streamable HTTP server-validation rules in the 2026-07-28
spec. Added unit tests covering the mapper directly (header-mismatch to
400, method-not-found to 404, an unmapped code defaulting to 200).

Closes modelcontextprotocol#1225

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@voidstackloop
voidstackloop requested a review from a team as a code owner September 11, 2026 12:20
@github-actions github-actions Bot added T-core Core library changes T-transport Transport layer changes labels Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-core Core library changes T-transport Transport layer changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Handler-generated HeaderMismatch responses use HTTP 200 instead of 400

1 participant