rohitg00/ai-engineering-from-scratch · error · RuntimeError
{peer.name}: unsupported legacy protocol revision
Error message
{peer.name}: unsupported legacy protocol revision What it means
The legacy initialize succeeded but the protocolVersion in the result is not in the client's supported_legacy set. The client only speaks an explicit allowlist of legacy revisions and refuses to proceed with one it has not been configured to accept.
Source
Thrown at phases/13-tools-and-protocols/08-building-an-mcp-client/code/main.py:389
raise RuntimeError(f"{peer.name}: bounded legacy probe failed closed") from exc
if not isinstance(response, dict):
raise RuntimeError(f"{peer.name}: bounded legacy probe returned no result")
kind, payload = decode_rpc_response(response, request_id)
if kind != "result":
raise RuntimeError(f"{peer.name}: legacy initialize returned an error")
result = payload
version = result.get("protocolVersion")
capabilities = result.get("capabilities")
server_info = result.get("serverInfo")
valid_server_info = (
isinstance(server_info, dict)
and isinstance(server_info.get("name"), str)
and bool(server_info["name"])
and isinstance(server_info.get("version"), str)
and bool(server_info["version"])
)
if version not in self.supported_legacy:
raise RuntimeError(f"{peer.name}: unsupported legacy protocol revision")
if not isinstance(capabilities, dict) or not valid_server_info:
raise RuntimeError(f"{peer.name}: malformed legacy initialize result")
peer.era = "legacy"
peer.protocol_version = version
peer.capabilities = capabilities
peer.server_info = server_info
peer.available = True
self._send(
peer,
{"jsonrpc": "2.0", "method": "notifications/initialized", "params": {}}
)
def _connect_peer(self, peer: Peer) -> None:
if peer.available and peer.era in {"modern", "legacy"}:
return
request_id = self._new_id()
probe = modern_request(
request_id,View on GitHub (pinned to 39ea8a1c6d)
Solutions
- Check what protocolVersion the server returned and compare with client.supported_legacy
- Add the server's revision to supported_legacy if it is actually safe to use
- Upgrade the server to a revision the client already allows
- Disable legacy for this peer and require a modern handshake
Example fix
// before
client = McpClient(..., supported_legacy={"2024-11-05"})
// after
client = McpClient(..., supported_legacy={"2024-11-05", "2025-03-26"}) Defensive patterns
Strategy: validation
Validate before calling
advertised = probe_server_protocol_version(peer)
if advertised not in client.supported_legacy:
align_versions(client, peer) # widen set or upgrade server before connect Type guard
null
Try / catch
try:
client.connect_all()
except RuntimeError as e:
if "unsupported legacy protocol revision" in str(e):
client.supported_legacy.add(reported_version(peer)) Prevention
- Pin supported_legacy explicitly and review it at every server upgrade
- Alert when a server's reported revision drifts
When it happens
Trigger: result.get('protocolVersion') from a successful legacy initialize returns a version string absent from self.supported_legacy.
Common situations: Server running a much older or newer legacy revision than the client anticipates; client's supported_legacy not updated after a server upgrade; server reporting an ad-hoc version string.
Related errors
- {peer.name}: legacy initialize returned an error
- {peer.name}: malformed legacy initialize result
- -32022
- -32022
- {peer.name}: {trigger}; legacy compatibility is not allowlis
AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26).
Data as JSON: /api/errors/8702484ae488cad5.
Report an issue: GitHub.