Kuberwastaken/claurst · error
MCP server ' ': HTTP from legacy SSE transport
Error message
MCP server '{}': HTTP {} from legacy SSE transport: {} What it means
After the SSE stream is established, JSON-RPC messages are POSTed to the server's message endpoint. This guard accepts 2xx and 202 Accepted, but any other non-success status on a POST response is fatal and reported with the server name, status, and body.
Solutions
- Reconnect the MCP session so a fresh endpoint event updates the POST URL
- Refresh OAuth credentials (re-run auth) if the status is 401/403
- Back off and retry if the status is 429, honoring any Retry-After header
- Inspect the body for 5xx and check server/proxy health
Defensive patterns
Strategy: retry
Try / catch
match client.send(msg).await {
Err(e) if e.to_string().contains("from legacy SSE transport: HTTP") => {
// 401/403: refresh credentials; 429: back off; 5xx: reconnect session
}
other => other?,
} Prevention
- Reconnect the session after any server restart to refresh the POST endpoint
- Refresh OAuth tokens before they expire during long sessions
- Implement backoff on 429 and surface 5xx bodies to server operators
When it happens
Trigger: handle_legacy_sse_http_response (reached from send and the message-queue handlers) receives an HTTP response whose status is neither success nor 202 ACCEPTED.
Common situations: Message endpoint URL became stale after a server restart; auth token expired mid-session (401); server rate-limiting (429); endpoint path wrong in proxy config (404); server crash returning 5xx.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- MCP server ' ': legacy SSE stream returned HTTP
- legacy SSE endpoint event did not include a POST endpoint
- invalid legacy SSE base URL
- failed to resolve legacy SSE endpoint
- MCP server ' ': legacy SSE POST request failed
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/b68141bbd4896583.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/mcp/src/rmcp_backend.rs:445
serde_json::from_str(data).map_err(|e| {
anyhow::anyhow!(
"MCP server '{}': failed to parse legacy SSE JSON payload: {}",
server_name,
e
)
})
}
async fn handle_legacy_sse_http_response(
server_name: String,
response: reqwest::Response,
incoming_tx: mpsc::UnboundedSender<rmcp::service::RxJsonRpcMessage<RoleClient>>,
background_tasks: Arc<StdMutex<Vec<JoinHandle<()>>>>,
) -> anyhow::Result<()> {
let status = response.status();
if !status.is_success() && status != reqwest::StatusCode::ACCEPTED {
let body = response.text().await.unwrap_or_default();
anyhow::bail!(
"MCP server '{}': HTTP {} from legacy SSE transport: {}",
server_name,
status,
body
);
}
if status == reqwest::StatusCode::ACCEPTED {
return Ok(());
}
if transport::is_event_stream_response(&response) {
let server_name_for_task = server_name.clone();
let task = tokio::spawn(async move {
if let Err(e) = transport::process_sse_response(response, |_, data| {
if data.trim().is_empty() {
return Ok(());
}View on GitHub (pinned to b0637c97ec)