Menu

AI

MCP Protocol Version Mismatch (Unsupported protocol version, -32022): How to Fix It (Claude Code, Inspector, SDKs)

Fix MCP protocol version errors: UnsupportedProtocolVersion -32022, ERA_NEGOTIATION_FAILED and 400 Bad Request between 2026-07-28 clients and 2025-era servers.

By: Irina ShvayaNovember 2, 2026

MCP Protocol Version Mismatch (Unsupported protocol version, -32022): How to Fix It (Claude Code, Inspector, SDKs)

This fix is part of MCP troubleshooting, within The MCP Guide. Still stuck? Request a free MCP readiness review.

A protocol version mismatch means your MCP client and server do not share a spec revision they both accept. Since the 2026-07-28 revision, there is no initialize handshake: every request names its version, and a server that does not support it returns UnsupportedProtocolVersionError (code -32022) with a list of versions it does support. The fastest fix is to let the client negotiate automatically (the default in the official SDKs) instead of pinning one version, or to update whichever side is older.

Checked against: the Versioning and Compatibility page and changelog of the 2026-07-28 spec, the TypeScript SDK troubleshooting guide and Claude Code's MCP docs on 2 November 2026 (TypeScript @modelcontextprotocol/server 2.4.0, Python mcp 2.3.0). eSEOspace did not run these steps.

Key Takeaways

  • The spec now has two eras: "legacy" (2025-11-25 and earlier, with an initialize handshake) and "modern" (2026-07-28, version sent on every request).
  • A modern server must answer an unsupported version with -32022 and a supported list; the client should retry with a shared version.
  • A legacy-only client cannot talk to a modern-only server at all. The spec's matrix says this combination "Fails."
  • The TypeScript SDK raises ERA_NEGOTIATION_FAILED locally when no era is shared, often because a version was pinned.
  • Claude Code exposes MCP_PROTOCOL_NEGOTIATION=legacy to skip the 2026-07-28 probe if a server misbehaves.

What this error means

The 2026-07-28 changelog made MCP stateless. It removed the initialize handshake, and every request carries its protocol version in _meta. On HTTP the same version travels in an MCP-Protocol-Version header. The versioning page says a server that does not implement the requested version "MUST respond with an UnsupportedProtocolVersionError listing the versions it does support." Its example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32022,
    "message": "Unsupported protocol version",
    "data": { "supported": ["2026-07-28", "2025-11-25"], "requested": "1900-01-01" }
  }
}

On Streamable HTTP this comes with 400 Bad Request. A related -32020 HeaderMismatch error means the header and the body named different versions.

The bigger source of trouble is mixing eras. The versioning page's compatibility matrix says:

ClientServerOutcome
ModernModernWorks
Dual-eraLegacyWorks (falls back to initialize)
LegacyDual-eraWorks
ModernLegacyFails
LegacyModernFails, often 400 Bad Request on HTTP

"Legacy clients have no fall-forward mechanism," the page notes. In 2025-era revisions, mismatches looked different: the 2025-11-25 lifecycle page had the server reply with another version, and a client that did not support it "SHOULD disconnect."

Quick fix

  1. Read the supported list in the error, if you got one. It tells you exactly which versions the server accepts.
  2. Remove any version pin in your client and use automatic negotiation.
  3. Update the older side. The official TypeScript and Python SDKs at v2 speak both eras as clients.
  4. If you own a modern-only server with old clients, add legacy support (the SDKs call it dual-era) until those clients upgrade.
  5. Retest with the MCP Inspector, setting its Protocol Era to auto.

Fix by client / OS

Claude Code

Claude Code's MCP docs describe two client runtimes. The v2 runtime, built on TypeScript SDK 2.0, asks HTTP and stdio servers whether they support 2026-07-28 and uses it with those that do. If a server breaks on that probe, set MCP_PROTOCOL_NEGOTIATION=legacy to skip it, or MCP_SDK_GENERATION=v1 to use the 1.x-based runtime. Per the environment variables page, the first needs Claude Code v2.1.221 or later and the second v2.1.218 or later.

TypeScript client (SDK v2)

The troubleshooting guide lists SdkError: ERA_NEGOTIATION_FAILED message tails. The most common is "the server did not offer pinned protocol version 2026-07-28 via server/discover (no fallback in pin mode)." Its fix:

const client = new Client({ name: 'app', version: '1.0.0' }, { versionNegotiation: { mode: 'auto' } });
await client.connect(transport);
console.log(client.getProtocolEra()); // "legacy" or "modern"

The guide adds that a 401 or 403 during the probe is not a version problem.

Python client (SDK v2)

The Python SDK's protocol versions page says mode="auto" is the default: one server/discover probe, then fallback. mode="legacy" forces the initialize handshake. Passing a 2025 version string as a pin raises ValueError: ... '2025-06-18' is a handshake-era version; use mode='legacy'.

MCP Inspector

Each server has a Protocol Era setting of legacy, auto or modern, per the Inspector protocol eras page. legacy is the default. The CLI accepts --protocol-era <legacy|auto|modern> for one run. See MCP Inspector connection errors.

Where to find the logs

  • Claude Code: claude --debug-file /tmp/claude-debug.log; unrecognized values for the two variables above are logged as warnings.
  • VS Code: MCP: List Servers > Show Output.
  • Claude Desktop: ~/Library/Logs/Claude/mcp*.log on macOS, %APPDATA%\Claude\logs on Windows, per the MCP debugging guide.
  • Your server: log the MCP-Protocol-Version header and the _meta version on each request.

If it still fails

  • 400 with an empty body. A legacy server or a proxy, not a modern error. A dual-era client falls back; a modern-only client cannot.
  • Probe hangs on stdio. The spec says dual-era clients treat a non-modern error or timeout as legacy. Check that your server writes nothing but JSON-RPC to stdout; see stdout logging breaks the server.
  • Method not found after connecting. You called a method from the other era. See -32601 method not found.
  • Version lookup. Our MCP spec version explorer and error code lookup list what changed in each revision.

Next step

If you maintain a server that must serve both 2025 and 2026 clients, eSEOspace's MCP development team can help plan a dual-era rollout. For the background, read our versioning and deprecation guide.

More in the MCP Guide

Free tools: MCP Error Code Lookup · MCP Config Generator

Latest research: State of MCP: October 2026

Frequently asked questions

What is error -32022 in MCP?

It is UnsupportedProtocolVersion, defined in the 2026-07-28 spec. Drafts of that revision used -32004; the changelog renumbered it to -32022 when it reserved -32020 to -32099 for the spec. The data.supported field lists versions the server accepts.

Which MCP protocol version should I use?

As of November 2026 the latest revision is 2026-07-28. Clients should negotiate automatically. Servers that still have 2025-era clients should support both eras until those clients upgrade.

Can a 2025 client talk to a 2026-07-28 server?

Only if the server is dual-era and still answers initialize. A modern-only server rejects the legacy handshake, and the spec says it "SHOULD name the protocol versions it supports" in that error.

Is server/discover required?

Servers must implement server/discover. Clients may call it first to learn supported versions, but they can also send any request and handle -32022 if their version is not supported.

You Might Also like to Read

Get a FREE Website Audit

Enter your website and get a 20–30 page SEO, GEO, AEO & CRO audit within 24 hours. Completely free.

Don't have a site yet? Get in touch →

Ready to speak with a marketing expert?
Give us a call! (916) 866-7893

Websites Launched
1407
Websites Launched
Marketing Experts
29
Marketing Experts
Hours of Dedicated Work
204533
Hours of Dedicated Work
Irina S.Benjamin G.Jeanette M.David G.