Skip to content

fix(streamable-http): map stale session 401 to status-aware error#709

Open
adam-r-kowalski wants to merge 1 commit intomodelcontextprotocol:mainfrom
adam-r-kowalski:fix/rmcp-stale-session-error-mapping
Open

fix(streamable-http): map stale session 401 to status-aware error#709
adam-r-kowalski wants to merge 1 commit intomodelcontextprotocol:mainfrom
adam-r-kowalski:fix/rmcp-stale-session-error-mapping

Conversation

@adam-r-kowalski
Copy link

Fixes #688.

This PR fixes streamable HTTP stale-session handling in the reqwest client: non-success HTTP responses are now surfaced as a status-aware transport error that preserves the HTTP status and response body (for example 401 Unauthorized: Session not found) instead of failing early with UnexpectedContentType(None) when Content-Type is missing.

Motivation and Context

When a stale or invalid mcp-session-id is sent to a stateful StreamableHttpService, the server correctly responds with 401 Unauthorized and a plain-text body. The client previously attempted content-type processing before handling non-success statuses, which hid the real failure as UnexpectedContentType(None).

This change makes stale-session and similar non-2xx HTTP failures actionable by preserving status/body context in UnexpectedServerResponse.

How Has This Been Tested?

Tested locally with:

cargo test -p rmcp --test test_streamable_http_stale_session --features "client server transport-streamable-http-client-reqwest transport-streamable-http-server"
cargo test -p rmcp --test test_streamable_http_priming --features "server client transport-streamable-http-server reqwest"
cargo test -p rmcp --test test_custom_headers --features "client server transport-streamable-http-client-reqwest transport-streamable-http-server"

Added regression test:

  • crates/rmcp/tests/test_streamable_http_stale_session.rs
    • Verifies stale session returns HTTP 401 from server.
    • Verifies client returns StreamableHttpError::UnexpectedServerResponse containing status/body context.

Breaking Changes

None. This is a bug fix in error mapping behavior for non-success responses.

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

Primary code change:

  • crates/rmcp/src/transport/common/reqwest/streamable_http_client.rs
    • Early return on non-success HTTP status with UnexpectedServerResponse("HTTP {status}: {body}").

This preserves server intent for stale-session failures and avoids misleading content-type errors when error responses do not include a Content-Type header.

@adam-r-kowalski adam-r-kowalski requested a review from a team as a code owner February 28, 2026 01:05
@github-actions github-actions bot added T-test Testing related changes T-core Core library changes T-transport Transport layer changes labels Feb 28, 2026
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.

streamable-http stale session returns UnexpectedContentType(None) instead of status-aware error

1 participant