Skip to content

fix: map HeaderMismatch to HTTP 400 - #1226

Open
lucarlig wants to merge 2 commits into
modelcontextprotocol:mainfrom
lucarlig:user/luca/header-mismatch-http-400
Open

fix: map HeaderMismatch to HTTP 400#1226
lucarlig wants to merge 2 commits into
modelcontextprotocol:mainfrom
lucarlig:user/luca/header-mismatch-http-400

Conversation

@lucarlig

@lucarlig lucarlig commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Map handler-generated JSON-RPC HeaderMismatch errors (-32020) to HTTP 400 on the modern per-request Streamable HTTP path. Add integration coverage for valid 2026-07-28 requests reaching a handler, with JSON responses and legacy session support each enabled and disabled. Verify HTTP status, JSON content type, request ID, error code, and the handler-generated message.

Fixes #1225.

Motivation and Context

The MCP 2026-07-28 Streamable HTTP server-validation rules require header-validation failures to return HTTP 400 with JSON-RPC error code -32020.

RMCP already returns that combination when its transport detects a mismatch before dispatch. However, when application validation returns ErrorData::header_mismatch(...) from a ServerHandler, the response flows through jsonrpc_http_status, where HEADER_MISMATCH previously fell through to HTTP 200.

This change adds HEADER_MISMATCH to the modern bad-request mapping. Legacy requests continue to bypass this mapper and retain their existing HTTP 200 JSON-RPC behavior.

Specification:

https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http#server-validation

How Has This Been Tested?

Rebased onto main at e27c5d1. All four regression configurations fail with HTTP 200 instead of 400 when the mapping is removed, and pass with the fix restored.

Ran:

cargo test -p rmcp --test test_streamable_http_json_response --test test_streamable_http_standard_headers --test test_streamable_http_protocol_version --test test_stateless_protocol_version --features server,client,transport-streamable-http-server,reqwest
cargo clippy -p rmcp --all-features --all-targets -- -D warnings
cargo fmt --all -- --check
git diff --check

Results: 49 focused tests passed. The 10-test JSON response suite also passed again after restoring the mapping. Clippy, formatting, and whitespace checks passed. Stable rustfmt emitted the repository's existing warnings for nightly-only configuration options.

Breaking Changes

None. This corrects the HTTP status for an existing modern JSON-RPC error response. The JSON-RPC error code and legacy response behavior are unchanged.

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

Related transport-level validation paths already construct HTTP 400 responses directly. The new test specifically covers a HeaderMismatch returned after handler dispatch.

@github-actions github-actions Bot added T-test Testing related changes T-core Core library changes T-transport Transport layer changes labels Aug 27, 2026
@lucarlig
lucarlig marked this pull request as ready for review September 11, 2026 09:18
@lucarlig
lucarlig requested a review from a team as a code owner September 11, 2026 09:18
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-11T09:21:00.213009Z 0d59e0a Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Signed-off-by: lucarlig <luca.carlig@ibm.com>
Signed-off-by: lucarlig <luca.carlig@ibm.com>
@lucarlig
lucarlig force-pushed the user/luca/header-mismatch-http-400 branch from 0d59e0a to c2b31b7 Compare September 11, 2026 09:46
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-test Testing related 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