PrefectHQ/fastmcp · error · ValueError
SSE transport does not support stateless mode
Error message
SSE transport does not support stateless mode
What it means
SSE (Server-Sent Events) is inherently a stateful transport, so FastMCP refuses to run it with stateless_http=True. run_http_async validates the combination up front and raises ValueError before starting uvicorn.
Source
Thrown at fastmcp_slim/fastmcp/server/mixins/transport.py:309
settings.http_host_origin_protection. "auto" protects
localhost-bound servers and explicit host/origin allowlists.
allowed_hosts: Additional hostnames that may appear in the Host header.
allowed_origins: Additional browser origins trusted by the request guard.
Configure CORS separately when browser JavaScript must read
cross-origin responses.
sockets: Pre-bound sockets to pass to Uvicorn
"""
# Allow stateless as alias for stateless_http
if stateless is not None and stateless_http is None:
stateless_http = stateless
# Resolve from settings/env var if not explicitly set
if stateless_http is None:
stateless_http = fastmcp.settings.stateless_http
# SSE doesn't support stateless mode
if stateless_http and transport == "sse":
raise ValueError("SSE transport does not support stateless mode")
host = host if host is not None else fastmcp.settings.host
port = port if port is not None else fastmcp.settings.port
resolved_host_origin_protection = (
host_origin_protection
if host_origin_protection is not None
else fastmcp.settings.http_host_origin_protection
)
resolved_allowed_hosts = _resolve_allowed_hosts_for_run(
host=host,
host_origin_protection=resolved_host_origin_protection,
allowed_hosts=allowed_hosts,
configured_allowed_hosts=fastmcp.settings.http_allowed_hosts,
)
default_log_level_to_use = (
log_level if log_level is not None else fastmcp.settings.log_level
).lower()
View on GitHub (pinned to 1f02114297)
Solutions
- Use transport='streamable-http' (or 'http') with stateless_http=True
- Set stateless_http=False (and unset FASTMCP_STATELESS_HTTP) when using SSE
Example fix
// before server.run(transport='sse', stateless_http=True) // after server.run(transport='http', stateless_http=True) # or keep sse without stateless
Defensive patterns
Strategy: validation
Validate before calling
if transport == 'sse' and (stateless_http or fastmcp.settings.stateless_http):
raise ValueError('Use streamable-http for stateless mode; SSE is stateful only') Try / catch
try:
await server.run_http_async(transport='sse', stateless_http=stateless)
except ValueError as e:
if 'stateless' in str(e):
await server.run_http_async(transport='http', stateless_http=stateless)
else:
raise Prevention
- Unset FASTMCP_STATELESS_HTTP when deploying SSE
- Keep transport and statelessness config co-located and validated together
- Prefer streamable-http for new stateless deployments
When it happens
Trigger: Calling run_http_async(transport='sse', stateless_http=True), or transport='sse' while fastmcp.settings.stateless_http is enabled (e.g. FASTMCP_STATELESS_HTTP=1).
Common situations: Deployments that globally enable stateless mode for scaling, then switch transport to 'sse'; copying a stateless config from a streamable-http deployment onto an SSE server.
Related errors
- Invalid transport: {transport}
- Unknown transport: {transport}
- Both 'httpx_client_factory' and 'verify' were provided. The
- Could not create the CLI state directory
- OAuth provider has no server URL. Either pass mcp_url to OAu
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/23623d23b4cf4cac.
Report an issue: GitHub.