PrefectHQ/fastmcp · error · InsufficientScopeError

Authorization failed for prompt '{prompt_name}': insufficien

Error message

Authorization failed for prompt '{prompt_name}': insufficient scope (required: {', '.join(missing)})

What it means

Raised as InsufficientScopeError when the prompt was found and component-level auth ran scope checks, but the caller's access token is missing one or more required scopes. The error message lists the exact missing scopes after the middleware chains any shortfall through _chain_shortfall (which can add parent/scope-group requirements).

Source

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

        # 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)
        authorized, missing = await run_auth_checks_with_shortfall(self.auth, ctx)
        if not authorized:
            if missing:
                missing = self._chain_shortfall(missing, ctx, fastmcp.fastmcp)
                raise InsufficientScopeError(
                    missing,
                    message=(
                        f"Authorization failed for prompt '{prompt_name}': "
                        f"insufficient scope (required: {', '.join(missing)})"
                    ),
                )
            raise AuthorizationError(
                f"Authorization failed for prompt '{prompt_name}': insufficient permissions"
            )

        return await call_next(context)

View on GitHub (pinned to 1f02114297)

Solutions

  1. Read the missing scopes from the error message and request a token containing them (re-run the OAuth flow with the expanded scope request).
  2. If the scopes are wrong on the server side, remove or relax required scopes in the prompt's auth configuration.
  3. Check _chain_shortfall expansion — the shortfall may include scopes inherited from scope groups/parents, so grant the base scope rather than each listed one.

Example fix

// before
await client.get_prompt("admin_report")  # token lacks admin:read

// after: obtain a token with the required scope
auth = OAuth(scopes=["admin:read"])
client = Client("http://localhost:8000/mcp", auth=auth)
await client.get_prompt("admin_report")
Defensive patterns

Strategy: try-catch

Validate before calling

// decode the token's scopes and compare to the prompt's requirements
claims = jwt.decode(token, options={"verify_signature": False})
have = set(claims.get("scope", "").split())
required = {"admin:read"}  # from prompt config
if not required <= have:
    raise PermissionError(f"token missing scopes: {required - have}")

Try / catch

try:
    result = await client.get_prompt(name)
except Exception as e:
    if "insufficient scope" in str(e):
        missing = str(e).split("required: ")[-1]
        token = await obtain_token(scopes=missing.split(", "))
        result = await client.get_prompt(name)
    else:
        raise

Prevention

When it happens

Trigger: on_get_prompt succeeded in fetching the prompt, run_auth_checks_with_shortfall returned authorized=False with a non-empty `missing` set — i.e. the prompt (or its auth config) declares required scopes the current token lacks.

Common situations: Token issued with narrower scopes than the prompt requires; provider scope mapping changed; prompt recently had required_scopes added; using a read-only API key for a prompt gated on admin scopes.

Related errors


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