Hmbown/CodeWhale · error
MCP SSE POST rejected (transport=sse endpoint={} status={}):
Error message
MCP SSE POST rejected (transport=sse endpoint={} status={}): {} What it means
The POST delivering a JSON-RPC message to the SSE endpoint returned a non-2xx status that is NOT classified as a stale session (no 'session expired/invalid' text in the body). The message carries the masked endpoint URL, the status, and a bounded, secret-scrubbed body excerpt for diagnosis.
Source
Thrown at crates/tui/src/mcp/sse.rs:306
format!(
"MCP SSE POST send failed (transport=sse endpoint={})",
mask_url_secrets(&endpoint)
)
})?;
let status = response.status();
if !status.is_success() {
let body_excerpt = bounded_body_excerpt(response, ERROR_BODY_PREVIEW_BYTES).await;
let stale_session = is_mcp_stale_session_body(&body_excerpt);
let body_excerpt = self.auth.server_error_preview(&body_excerpt);
if stale_session {
anyhow::bail!(
"MCP session expired (transport=sse endpoint={} status={}): {}",
mask_url_secrets(&endpoint),
status,
body_excerpt
);
}
anyhow::bail!(
"MCP SSE POST rejected (transport=sse endpoint={} status={}): {}",
mask_url_secrets(&endpoint),
status,
body_excerpt
);
}
Ok(())
}
async fn recv(&mut self) -> Result<Vec<u8>> {
loop {
match self.receiver.recv().await.context("SSE transport closed")? {
SseInbound::Endpoint(endpoint) => {
self.store_endpoint(&endpoint)?;
}
SseInbound::Message(msg) => return Ok(msg),
}
}View on GitHub (pinned to 8880682c63)
Solutions
- Read the status and body excerpt embedded in the message — they state the actual failure
- On 401/403: refresh OAuth credentials and reconnect
- On 400: log the exact request JSON; the payload likely violates the server's schema for that method
- On 5xx: check server logs and retry with backoff once the server recovers
Defensive patterns
Strategy: try-catch
Type guard
```rust
fn sse_post_status(err: &anyhow::Error) -> Option<u16> {
let msg = format!("{err:#}");
msg.split("status=").nth(1)?.split(']').next()? // e.g. "404): ..."
.chars().take_while(char::is_ascii_digit)
.collect::<String>().parse().ok()
}
``` Try / catch
```rust
match transport.send(payload).await {
Err(e) if e.to_string().contains("MCP SSE POST rejected") => match sse_post_status(&e) {
Some(s) if (500..600).contains(&s) => retry_with_backoff().await,
Some(401) | Some(403) => reauthenticate_and_reconnect().await,
_ => { log_body_excerpt(&e); return Err(e); }
},
other => other,
}
``` Prevention
- Log the embedded body excerpt verbatim — it is already bounded and secret-scrubbed
- Refresh auth before long sessions to avoid mid-session 401/403 POST failures
When it happens
Trigger: POST to the endpoint event's URL answers 401/403 (auth header rejected), 400 (server rejects the JSON-RPC payload), 413, or a 5xx while processing a specific tool call.
Common situations: Token expired or revoked between connect and send; gateway rules (size, auth) on the POST route; server-side exception triggered by one particular tool call or resource read.
Related errors
- MCP SSE rejected (transport=http url={} status={}): {}
- MCP Streamable HTTP rejected (transport=http url={} status={
- Runtime API request failed (${status}): ${message}
- SSE stream request failed: HTTP {status}: {error_text}
- MCP session expired: {error}
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/5524276bd2e5448a.
Report an issue: GitHub.