Kuberwastaken/claurst · error · anyhow::Error

MCP server ' ': invalid streamable HTTP protocol version

Error message

MCP server '{}': invalid streamable HTTP protocol version '{}': {}

What it means

When connecting a streamable-HTTP MCP server, the client iterates STREAMABLE_HTTP_PROTOCOL_VERSIONS and deserializes each into rmcp::model::ProtocolVersion. This error fires if one of the compiled-in protocol version strings fails that deserialization — i.e. a library/build inconsistency, since these are constants the library itself controls.

Solutions

  1. Update the rmcp crate to a version whose ProtocolVersion accepts the strings in STREAMABLE_HTTP_PROTOCOL_VERSIONS
  2. Remove/correct the offending entry in STREAMABLE_HTTP_PROTOCOL_VERSIONS (crates/mcp transport)
  3. Run cargo update to reconcile duplicate rmcp versions in the workspace
  4. Check the serde error in the message to see why the version string was rejected

Example fix

// before
pub const STREAMABLE_HTTP_PROTOCOL_VERSIONS: &[&str] = &["2026-01-01"];
// after
pub const STREAMABLE_HTTP_PROTOCOL_VERSIONS: &[&str] = &["2025-03-26", "2024-11-05"];
Defensive patterns

Strategy: retry

Try / catch

match connect(cfg).await {
    Err(e) if e.to_string().contains("invalid streamable HTTP protocol version") => {
        // dependency/build issue: fail fast, surface upgrade guidance
    }
    r => r?,
}

Prevention

When it happens

Trigger: Transport::connect_http loop over transport::STREAMABLE_HTTP_PROTOCOL_VERSIONS where a version string (e.g. "2025-03-26") is not accepted by rmcp's ProtocolVersion deserializer — typically after a rmcp crate upgrade that dropped or changed accepted version formats.

Common situations: Mismatched rmcp dependency versions in Cargo.lock; someone edited STREAMABLE_HTTP_PROTOCOL_VERSIONS to an rmcp-unsupported string; vendored/patched rmcp with stricter parsing.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10). Data as JSON: /api/errors/523d91b7b632274f. Report an issue: GitHub.

Appendix: source

Thrown at src-rust/crates/mcp/src/lib.rs:609

        pub async fn connect(config: &McpServerConfig, auth_token: Option<String>) -> anyhow::Result<Self> {
            match config.server_type.as_str() {
                "stdio" => Self::connect_stdio(config).await,
                "sse" => {
                    let backend = crate::rmcp_backend::RmcpClientBackend::connect_legacy_sse(
                        config,
                        auth_token,
                    )
                    .await?;
                    Ok(Self::from_backend(Arc::new(backend)))
                }
                "http" => {
                    let mut last_error = None;
                    for &protocol_version in transport::STREAMABLE_HTTP_PROTOCOL_VERSIONS {
                        let protocol_version = serde_json::from_value::<rmcp::model::ProtocolVersion>(
                            Value::String(protocol_version.to_string()),
                        )
                        .map_err(|e| {
                            anyhow::anyhow!(
                                "MCP server '{}': invalid streamable HTTP protocol version '{}': {}",
                                config.name,
                                protocol_version,
                                e
                            )
                        })?;
                        let protocol_version_label = protocol_version.as_str().to_string();
                        match crate::rmcp_backend::RmcpClientBackend::connect_http(
                            config,
                            auth_token.clone(),
                            protocol_version,
                        )
                        .await
                        {
                            Ok(backend) => return Ok(Self::from_backend(Arc::new(backend))),
                            Err(e) => {
                                let message = e.to_string();
                                if Self::is_unsupported_protocol_error(&message) {

View on GitHub (pinned to b0637c97ec)