Skip to content

fix: propagate auth errors (401/403) immediately instead of falling b…#1444

Open
xue-cai wants to merge 1 commit intomodelcontextprotocol:mainfrom
xue-cai:fix/auto-detect-propagate-auth-errors
Open

fix: propagate auth errors (401/403) immediately instead of falling b…#1444
xue-cai wants to merge 1 commit intomodelcontextprotocol:mainfrom
xue-cai:fix/auto-detect-propagate-auth-errors

Conversation

@xue-cai
Copy link

@xue-cai xue-cai commented Mar 16, 2026

…ack to SSE

When AutoDetectingClientSessionTransport receives a 401 or 403 from the initial Streamable HTTP POST, it should NOT fall back to SSE transport. Auth errors are not transport-related — the server understood the request but rejected the credentials. Falling back to SSE would:

  1. Fail with the same credentials (or a different transport error)
  2. Mask the real authentication error from the caller

This was discovered investigating Azure AI Search MCP endpoints returning 403 on Streamable HTTP POST, which caused the SDK to fall back to SSE GET, resulting in a confusing 405 error that hid the real auth failure.

The fix adds an explicit check for 401/403 before the SSE fallback path, and throws HttpRequestException with the auth status code immediately.

Code reference:
AutoDetectingClientSessionTransport.InitializeAsync
https://github.com/modelcontextprotocol/csharp-sdk/blob/v0.9.0-preview.2/src/ModelContextProtocol.Core/Client/AutoDetectingClientSessionTransport.cs#L61

Motivation and Context

How Has This Been Tested?

Breaking Changes

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

…ack to SSE

When AutoDetectingClientSessionTransport receives a 401 or 403 from the
initial Streamable HTTP POST, it should NOT fall back to SSE transport.
Auth errors are not transport-related — the server understood the request
but rejected the credentials. Falling back to SSE would:

1. Fail with the same credentials (or a different transport error)
2. Mask the real authentication error from the caller

This was discovered investigating Azure AI Search MCP endpoints returning
403 on Streamable HTTP POST, which caused the SDK to fall back to SSE GET,
resulting in a confusing 405 error that hid the real auth failure.

The fix adds an explicit check for 401/403 before the SSE fallback path,
and throws HttpRequestException with the auth status code immediately.

Code reference:
  AutoDetectingClientSessionTransport.InitializeAsync
  https://github.com/modelcontextprotocol/csharp-sdk/blob/v0.9.0-preview.2/src/ModelContextProtocol.Core/Client/AutoDetectingClientSessionTransport.cs#L61

Testing:
  # Build (two warnings suppressed are pre-existing on main, not related to this change):
  dotnet build '/p:NoWarn=NU1903%3BMCPEXP001'

  # Run all transport tests on all 3 target frameworks (73 tests × 3 = 219 total, 0 failures):
  dotnet test tests/ModelContextProtocol.Tests/ '/p:NoWarn=NU1903%3BMCPEXP001' --no-build --filter "FullyQualifiedName~Transport" --framework net10.0
  dotnet test tests/ModelContextProtocol.Tests/ '/p:NoWarn=NU1903%3BMCPEXP001' --no-build --filter "FullyQualifiedName~Transport" --framework net9.0
  dotnet test tests/ModelContextProtocol.Tests/ '/p:NoWarn=NU1903%3BMCPEXP001' --no-build --filter "FullyQualifiedName~Transport" --framework net8.0

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@xue-cai xue-cai force-pushed the fix/auto-detect-propagate-auth-errors branch from 158fc82 to 7405d8b Compare March 16, 2026 21:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant