PrefectHQ/fastmcp · error · AuthorizationError

Authorization failed for resource '{uri}': not found or not

Error message

Authorization failed for resource '{uri}': not found or not authorized

What it means

For resources/read, AuthMiddleware resolves the component via `get_resource(uri, version)` and, failing that, `get_resource_template(uri, version)`; when both return None it raises this AuthorizationError. Both 'does not exist' and 'exists but component-level auth hid it' map to the same deliberately ambiguous message so resource existence is not disclosed to unauthorized callers.

Source

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

                "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"
            )

        # Global auth check
        token = get_access_token()
        ctx = AuthContext(token=token, component=component)
        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 resource '{uri}': "
                        f"insufficient scope (required: {', '.join(missing)})"
                    ),
                )

View on GitHub (pinned to 1f02114297)

Solutions

  1. List resources/templates as the authorized client (`session.list_resources()` / `list_resource_templates()`) and use an exact returned URI.
  2. Check the URI against the template pattern; supply parameters in the expected format (e.g. 'data://42' not 'data?id=42').
  3. If the component requires auth, grant the caller's token the configured scopes/roles so the lookup stops being filtered.
  4. Verify the requested version in _meta exists, or omit it to get the default variant.

Example fix

# before
await client.read_resource('config://app')  # server only has 'config://{env}'
# after
templates = await client.list_resource_templates()
uri = templates[0].uri_template.replace('{env}', 'prod')
await client.read_resource(uri)
Defensive patterns

Strategy: validation

Validate before calling

uris = {str(r.uri) for r in await client.list_resources()}
uris |= {t.uri_template for t in await client.list_resource_templates()}
assert uri in uris, 'URI not visible to this caller; check format and auth'

Try / catch

from fastmcp.exceptions import AuthorizationError
try:
    res = await client.read_resource(uri)
except AuthorizationError as e:
    if 'not found or not authorized' in str(e):
        known = await client.list_resources()
        logger.warning('URI %s unavailable; known: %s', uri, [str(r.uri) for r in known])
    else:
        raise

Prevention

When it happens

Trigger: Client requests a URI that matches no registered resource or resource template, a URI that doesn't match the template pattern (e.g. wrong parameter format for 'data://{id}'), a version requested via _meta with no matching variant, or component-level auth denying this caller so lookup returns None.

Common situations: URI escaping/format mismatches against a resource template (missing scheme, query instead of path parameter); client caching a URI from a renamed resource; versioned component variants removed; resource hidden by auth policy for this token.

Related errors


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