Editorial

Research guide · MCP interoperability · 13 September 2026

MCP HeaderMismatch (-32020): fix x-mcp-header and Mcp-Param errors

A -32020 HeaderMismatch, missing Mcp-Param-owner or unexplained HTTP 400 on a modern MCP tool call usually means the transport headers and JSON-RPC body no longer describe the same request. MCP 2026-07-28 made those headers part of the Streamable HTTP routing contract, and current SDKs are still exposing edge cases around tool-definition caches and recovery.

Published 13 September 2026 · sources checked 13 September 2026

-32020

Current HeaderMismatch error code

2026-07-28

MCP revision that standardised the modern routing headers

Mcp-Method

Mirrors the JSON-RPC method for modern HTTP routing

Mcp-Param-*

Mirrors only tool parameters explicitly annotated with x-mcp-header

What changed

MCP requests became routable without parsing the JSON body

MCP 2026-07-28 moved the protocol core toward stateless request/response HTTP. On the modern Streamable HTTP path, requests carry MCP-Protocol-Version plus routing information such as Mcp-Method and, where the request has a principal name, Mcp-Name. Gateways can route and authorize the call from headers, but that only works safely if the headers agree with the JSON-RPC body.

SEP-2243 also lets a tool mark selected primitive input properties with x-mcp-header. A conforming client mirrors those argument values into headers such as Mcp-Param-Owner. The server validates the mirrored value against the body before dispatch. Missing, malformed or conflicting values are rejected rather than trusted.

Current official SDK documentation assigns -32020 to HeaderMismatch. Some older proposal text still shows the pre-final allocation -32001; do not hard-code the historical number when diagnosing a current 2026-07-28 implementation.

Fast diagnosis

Map the exact error to the boundary that failed

SignalLikely boundaryFirst action
missing Mcp-MethodA modern Streamable HTTP request did not carry the JSON-RPC method in the required routing header.Confirm the request negotiated 2026-07-28 and let a current SDK generate Mcp-Method from the body method.
Mcp-Name mismatchThe routing name in the header and the principal request name in the body disagree.Compare Mcp-Name with the exact tool, prompt, resource or task identifier in the JSON-RPC request.
missing Mcp-Param-ownerA tool schema declares x-mcp-header for owner, but the client sent the body argument without the mirrored header.Refresh the tool definition and ensure the current HTTP client knows the x-mcp-header annotation before tools/call.
HeaderMismatch after a tool changedThe client may be using a stale cached tools/list definition while the server validates against a newer schema.Re-list tools, invalidate the relevant catalog cache and retry once with the current definition.
Works on legacy, fails on 2026-07-28The stricter modern HTTP path validates standard and annotated routing headers against the body.Fix the modern request instead of suppressing validation or silently downgrading protocol versions.
Works on one SDK, fails on anotherThe protocol rule may be valid while one SDK still has a recovery, declaration or compatibility gap.Check the SDK's 2026-07-28 support notes and current issue tracker before changing server semantics.

Repair sequence

Seven checks before changing server behavior

  1. 1. Confirm the negotiated protocol version. If the request claims 2026-07-28, debug it as a modern request. Do not assume a server URL implies one protocol era.
  2. 2. Inspect the actual failing HTTP request. Compare MCP-Protocol-Version, Mcp-Method and Mcp-Name with the corresponding JSON-RPC fields rather than looking only at SDK logs.
  3. 3. Fetch the current tool definition. Re-run tools/list or use the SDK's supported explicit tool-definition option so the client sees any current x-mcp-header annotations.
  4. 4. Mirror only annotated parameters. If owner is annotated as x-mcp-header: "owner", send the body argument and its matching Mcp-Param-owner value together. Unannotated arguments do not need custom MCP parameter headers.
  5. 5. Check encoding and types. Current SDK guidance limits these routed properties to supported primitive types and applies transport encoding where necessary. Let the SDK codec do this when possible instead of manually inventing header serialization.
  6. 6. Treat a retry as schema recovery, not brute force. If the failure was caused by a stale tool definition, refresh the definition once and retry with the same logical operation. Repeating the same malformed request does not improve interoperability.
  7. 7. If it is SDK-specific, isolate the compatibility gap. Reproduce the same tool definition and call with a known-conforming SDK before weakening server validation. A client bug and a protocol requirement are different verdicts.

Current SDK traps

Fresh issue reports show why “the schema looks right” is not enough

Two open Python SDK issues from 9 September 2026 focus directly on this boundary. One reports that the client does not yet perform the expected recovery after -32020 when it did not already know the tool's x-mcp-header map. Another reports that the high-level server API can expose an invalid annotation without a declaration/validation path that makes the intended header behavior usable end to end. These are implementation reports, not changes to the protocol contract.

A separate TypeScript SDK issue documents a different compatibility hole: a hosted server required Mcp-Param-* headers while negotiation had fallen back to an older protocol era, but the SDK intentionally gated automatic mirroring to modern 2026-07-28 connections. The lesson is not to send modern headers everywhere. It is to identify the negotiated era and the server's actual requirement before choosing a workaround.

Browsers add another boundary: dynamically named custom headers can interact badly with credentialed CORS policy. If a browser client fails while a server-side client works, inspect preflight and SDK browser behavior before blaming the tool schema.

Security

Do not turn routing metadata into a secret channel

x-mcp-header exists to expose selected routing-relevant tool parameters to HTTP infrastructure. That makes those values easier for gateways, proxies, observability systems and logs to see. Do not annotate API keys, bearer tokens, private credentials or unnecessary personal information merely to make a call pass.

Keep authentication in the MCP authorization flow and use header-routed tool parameters only where the server intentionally needs that non-secret value for routing, rate limiting, authorization policy or infrastructure selection. A request that cannot be represented safely should fail closed rather than leak a secret into infrastructure metadata.

Related zFinia guides

Continue from transport integrity into trust and authorization

Sources

Primary specification and implementation references