PrefectHQ/fastmcp · error · ValueError

Invalid URL for configuration metadata: {attr}

Error message

Invalid URL for configuration metadata: {attr}

What it means

Strict-mode metadata validation found a required URL-typed field (issuer, authorization_endpoint, token_endpoint, or jwks_uri) that is populated but not a valid http(s) URL. AnyHttpUrl parsing fails and the original parse error is chained.

Source

Thrown at fastmcp_slim/fastmcp/server/auth/oidc_proxy.py:138

        if not self.strict:
            return self

        def enforce(attr: str, is_url: bool = False) -> None:
            value = getattr(self, attr, None)
            if not value:
                message = f"Missing required configuration metadata: {attr}"
                logger.error(message)
                raise ValueError(message)

            if not is_url or isinstance(value, AnyHttpUrl):
                return

            try:
                AnyHttpUrl(value)
            except Exception as e:
                message = f"Invalid URL for configuration metadata: {attr}"
                logger.error(message)
                raise ValueError(message) from e

        enforce("issuer", True)
        enforce("authorization_endpoint", True)
        enforce("token_endpoint", True)
        enforce("jwks_uri", True)
        enforce("response_types_supported")
        enforce("subject_types_supported")
        enforce("id_token_signing_alg_values_supported")

        return self

    @classmethod
    def get_oidc_configuration(
        cls, config_url: AnyHttpUrl, *, strict: bool | None, timeout_seconds: int | None
    ) -> Self:
        """Get the OIDC configuration for the specified config URL.

        Args:

View on GitHub (pinned to 1f02114297)

Solutions

  1. Fix the offending field in the provider's discovery document or your explicit config so it is a valid absolute http(s) URL
  2. Check for unexpanded env-var placeholders or whitespace in configuration
  3. If the provider metadata is wrong, override the endpoints with correct values in your proxy configuration

Example fix

// before
issuer = "${OIDC_ISSUER}"  # never expanded
// after
issuer = "https://idp.example.com"  # valid absolute URL
Defensive patterns

Strategy: validation

Validate before calling

from pydantic import AnyHttpUrl
for field in ("issuer", "authorization_endpoint", "token_endpoint", "jwks_uri"):
    AnyHttpUrl(meta[field])  # raises if not a valid absolute http(s) URL

Type guard

def is_valid_url(v: object) -> bool:
    try:
        AnyHttpUrl(v)  # type: ignore[arg-type]
        return True
    except Exception:
        return False

Try / catch

try:
    proxy = OIDCProxy(config_url=..., strict=True)
except ValueError as e:
    logger.error("invalid metadata URL: %s", e)
    raise SystemExit(1)

Prevention

When it happens

Trigger: Discovery metadata (or manually supplied config) contains a malformed or relative URL for one of the four enforced URL fields — e.g. issuer missing scheme, trailing whitespace, or an 'example' placeholder.

Common situations: Providers behind reverse proxies emitting http:// where https:// is expected or relative endpoint paths; copy-pasted config with typos; environment-substituted URLs left as empty templates like '${ISSUER}'.

Related errors


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