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

  1. Use transport='streamable-http' (or 'http') with stateless_http=True
  2. 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

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


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/23623d23b4cf4cac. Report an issue: GitHub.