PrefectHQ/fastmcp · error · AuthorizationError

Authorization failed for resource '{uri}': missing context

Error message

Authorization failed for resource '{uri}': missing context

What it means

AuthMiddleware.on_read_resource fails closed when `context.fastmcp_context` is None for a resources/read request: without the request-scoped FastMCP Context it cannot perform authorization checks, so it denies access with an AuthorizationError. This guards against requests reaching auth middleware outside the normal context-establishing dispatch path.

Source

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

        context: MiddlewareContext[mt.ReadResourceRequestParams],
        call_next: CallNext[mt.ReadResourceRequestParams, ResourceResult],
    ) -> ResourceResult:
        """Check auth before resource read."""
        # 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 resource being read
        uri = context.message.uri
        fastmcp = context.fastmcp_context
        if fastmcp is None:
            logger.warning(
                f"AuthMiddleware: fastmcp_context is None for resource '{uri}'. "
                "Denying access for security."
            )
            raise AuthorizationError(
                f"Authorization failed for resource '{uri}': missing context"
            )

        # get_resource/get_resource_template return None both when the resource
        # 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 resources the caller is not authorized to see.
        version = _requested_version(context.message.meta)
        component = await fastmcp.fastmcp.get_resource(str(uri), version=version)
        if component is None:
            component = await fastmcp.fastmcp.get_resource_template(
                str(uri),
                version=version,
            )
        if component is None:
            raise AuthorizationError(
                f"Authorization failed for resource '{uri}': "
                "not found or not authorized"

View on GitHub (pinned to 1f02114297)

Solutions

  1. Perform the read through the standard client -> server dispatch so FastMCP establishes the request Context.
  2. In tests, wrap handler execution in `async with Context(fastmcp=mcp, session=...)` and pass it as fastmcp_context in MiddlewareContext.
  3. Update custom transport/middleware glue to establish a FastMCP Context per request, mirroring the built-in transports.
  4. Ensure the transport is registered so _current_transport is set correctly for the request.

Example fix

# before (test)
ctx = MiddlewareContext(message=ReadResourceRequestParams(uri=uri), fastmcp_context=None)
await mw.on_read_resource(ctx, call_next)  # AuthorizationError: missing context
# after
async with Context(fastmcp=mcp, session=session) as fctx:
    ctx = MiddlewareContext(message=ReadResourceRequestParams(uri=uri), fastmcp_context=fctx)
    await mw.on_read_resource(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, 'resources/read middleware requires a FastMCP context'

Try / catch

from fastmcp.exceptions import AuthorizationError
try:
    res = await client.read_resource(uri)
except AuthorizationError as e:
    if 'missing context' in str(e):
        logger.error('resources/read reached auth middleware without context; fix dispatch path')
    else:
        raise

Prevention

When it happens

Trigger: resources/read on a non-stdio transport where the MiddlewareContext was constructed without fastmcp_context — direct middleware invocation in tests, custom transports or ASGI glue that bypasses `Context` setup, or middleware wrapping that drops the request context.

Common situations: Hand-built MiddlewareContext in unit tests; embedding the low-level server in a custom HTTP handler that skips Context establishment; framework upgrades where custom transport code no longer matches FastMCP's context setup.

Related errors


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