PrefectHQ/fastmcp · warning · UserWarning

Both 'httpx_client_factory' and 'verify' were provided. The

Error message

Both 'httpx_client_factory' and 'verify' were provided. The 'verify' parameter will be ignored because 'httpx_client_factory' takes precedence. Configure SSL verification directly in your httpx_client_factory instead.

What it means

Same conflict as in the http transport: `SSETransport` accepts `verify` and `httpx_client_factory`; when both are provided the factory wins and `verify` is ignored, raising a `UserWarning` from `__init__`.

Source

Thrown at fastmcp_slim/fastmcp/client/transports/sse.py:65

        verify: ssl.SSLContext | bool | str | None = None,
    ):
        if isinstance(url, AnyUrl):
            url = str(url)
        if not isinstance(url, str) or not url.startswith("http"):
            raise ValueError("Invalid HTTP/S URL provided for SSE.")

        # Don't modify the URL path - respect the exact URL provided by the user
        # Some servers are strict about trailing slashes (e.g., PayPal MCP)

        self.url: str = url
        self.headers = headers or {}
        self.httpx_client_factory = httpx_client_factory
        self.verify: ssl.SSLContext | bool | str | None = verify

        if httpx_client_factory is not None and verify is not None:
            import warnings

            warnings.warn(
                "Both 'httpx_client_factory' and 'verify' were provided. "
                "The 'verify' parameter will be ignored because "
                "'httpx_client_factory' takes precedence. Configure SSL "
                "verification directly in your httpx_client_factory instead.",
                UserWarning,
                stacklevel=2,
            )

        self._set_auth(auth)

        self.sse_read_timeout = normalize_timeout_to_timedelta(sse_read_timeout)

    def _set_auth(self, auth: httpx2.Auth | Literal["oauth"] | str | None):
        resolved: httpx2.Auth | None
        if auth == "oauth":
            resolved = OAuth(
                self.url,
                httpx_client_factory=self.httpx_client_factory

View on GitHub (pinned to 1f02114297)

Solutions

  1. Move the SSL setting into the factory: `httpx.AsyncClient(verify="certs/ca.pem", ...)`.
  2. Remove the redundant `verify=` argument.
  3. Or keep `verify` and drop the factory if a default client suffices.
  4. Add a config-layer assertion that only one of the two is set.

Example fix

// before
SSETransport(url, verify="ca.pem", httpx_client_factory=lambda **kw: httpx.AsyncClient(**kw))
// after
def factory(**kw):
    return httpx.AsyncClient(verify="ca.pem", **kw)
SSETransport(url, httpx_client_factory=factory)
Defensive patterns

Strategy: validation

Validate before calling

assert not (httpx_client_factory is not None and verify is not None), "Configure SSL in the httpx_client_factory instead of passing verify"

Try / catch

import warnings
with warnings.catch_warnings(record=True) as caught:
    warnings.simplefilter("always")
    t = SSETransport(url, verify=verify, httpx_client_factory=factory)
if any("'verify' parameter will be ignored" in str(w.message) for w in caught):
    logging.warning("verify ignored by SSETransport; move SSL into factory")

Prevention

When it happens

Trigger: `SSETransport(url, verify="certs/ca.pem", httpx_client_factory=factory)` — any non-None combination of both arguments.

Common situations: Migrating SSE transports from plain `verify=` usage to custom httpx client factories; shared config builders that always set both.

Understand the failure class

Related errors


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