Symptom
SSEClientTransport.start() never settles when the EventSource GET keeps returning 401 and onUnauthorized() keeps resolving. The transport rebuilds the EventSource with no cap.
Evidence what you'll see
- On
mainatdd22ba25, a local server that always answers 401 and a provider that always resolves measuredEventSource GET attempts (1.5 s) : 25andonUnauthorized() invocations : 25, withstart()never settled. The 25 was a backstop; without it the event loop is starved. - The same transport's POST path stops:
POST attempts : 2,onUnauthorized() invocations : 1,send()rejected withSdkHttpError: Server returned 401 after re-authentication. - A comment on 30 Sep 2026 reproduced the loop at
attempts: 13873before pull request 2905, andattempts: 2withSdkHttpError: Server returned 401 after re-authenticationafter it.
Why it happens
The documented contract on onUnauthorized is retry once, then throw. The SSE stream called _startOrAuth() fresh on every 401, so a resolving no-op provider rebuilt the connection forever. Pull request 2905 adds _connectAuthRetried, retries once, and on a second 401 before the stream opens rejects with SdkHttpError (ClientHttpAuthentication, Server returned 401 after re-authentication). The guard clears when the stream opens, so a later reconnect still gets one refresh.
Affected versions
@modelcontextprotocol/sdk on main at dd22ba25, Node 22, macOS, local HTTP server. The reproduction in the 30 Sep 2026 comment imports SSEClientTransport from @modelcontextprotocol/client.
Fix steps
0 of 2 done
Your check marks stay in this browser only.
How to check it worked
- Against a server that always returns 401,
start()rejects withSdkHttpError: Server returned 401 after re-authentication,onUnauthorizedruns once, and there are two EventSourceGETs.
If it still fails
- A later 401 after the stream has opened still refreshes once. The pull request says that is intended.
- The linked issue does not describe an unbounded 401 loop on
@modelcontextprotocol/client2.3.0.
Sources and credit
Summarized in our own words from these public reports. Credit goes to their authors.
Provided as is, without warranty. Try changes in a non-production environment and back up first. Security-related steps: verify against the official docs. Terms · Request removal or attribution change
Hit an error we don't cover? Submit it