PrefectHQ/fastmcp · error · AuthorizationError

Authorization failed for prompt '{prompt_name}': missing con

Error message

Authorization failed for prompt '{prompt_name}': missing context

What it means

AuthMiddleware.on_get_prompt fails closed when `context.fastmcp_context` is None for a prompts/get request: authorization cannot be evaluated without the request-scoped FastMCP Context, so it denies access with an AuthorizationError. Reaching this state indicates the request bypassed the dispatch paths that establish a Context.

Source

Thrown at fastmcp_slim/fastmcp/server/middleware/authorization.py:420

        context: MiddlewareContext[mt.GetPromptRequestParams],
        call_next: CallNext[mt.GetPromptRequestParams, PromptResult],
    ) -> PromptResult:
        """Check auth before prompt render."""
        # STDIO has no auth concept, skip enforcement
        from fastmcp.server.context import _current_transport

        if _current_transport.get() == "stdio":
            return await call_next(context)

        # Get the prompt being rendered
        prompt_name = context.message.name
        fastmcp = context.fastmcp_context
        if fastmcp is None:
            logger.warning(
                f"AuthMiddleware: fastmcp_context is None for prompt '{prompt_name}'. "
                "Denying access for security."
            )
            raise AuthorizationError(
                f"Authorization failed for prompt '{prompt_name}': missing context"
            )

        # get_prompt returns None both when the prompt does not exist and when
        # component-level auth denied access, so the two cases are
        # indistinguishable here. Keep the message ambiguous to avoid
        # disclosing existence of prompts the caller is not authorized to see.
        version = _requested_version(context.message.meta)
        prompt = await fastmcp.fastmcp.get_prompt(prompt_name, version=version)
        if prompt is None:
            raise AuthorizationError(
                f"Authorization failed for prompt '{prompt_name}': "
                "not found or not authorized"
            )

        # Global auth check
        token = get_access_token()
        ctx = AuthContext(token=token, component=prompt)

View on GitHub (pinned to 1f02114297)

Solutions

  1. Invoke prompt rendering through the standard client -> server dispatch so the Context is established automatically.
  2. In tests, run inside `async with Context(fastmcp=mcp, session=...)` and supply that as fastmcp_context to MiddlewareContext.
  3. Update custom transport code to establish a FastMCP Context per request like the built-in transports.
  4. Verify the transport detection (_current_transport) matches the actual transport in use.

Example fix

# before (test)
ctx = MiddlewareContext(message=GetPromptRequestParams(name='greet'), fastmcp_context=None)
await mw.on_get_prompt(ctx, call_next)  # AuthorizationError: missing context
# after
async with Context(fastmcp=mcp, session=session) as fctx:
    ctx = MiddlewareContext(message=GetPromptRequestParams(name='greet'), fastmcp_context=fctx)
    await mw.on_get_prompt(ctx, call_next)
Defensive patterns

Strategy: try-catch

Validate before calling

async with Context(fastmcp=mcp, session=session) as fctx:
    assert fctx is not None, 'prompts/get middleware requires a FastMCP context'

Try / catch

from fastmcp.exceptions import AuthorizationError
try:
    prompt = await client.get_prompt('greet', {'name': 'world'})
except AuthorizationError as e:
    if 'missing context' in str(e):
        logger.error('prompts/get reached auth middleware without context; fix dispatch path')
    else:
        raise

Prevention

When it happens

Trigger: prompts/get on a non-stdio transport with a MiddlewareContext lacking fastmcp_context — direct middleware calls in tests, custom transports/handlers that skip `Context` setup, or middleware wrapping that loses the request context.

Common situations: Unit tests constructing MiddlewareContext by hand; custom ASGI/transport integration that predates or bypasses FastMCP's context establishment; upgrades where custom glue no longer matches FastMCP internals.

Related errors


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