BerriAI/litellm · error · ValueError

Refusing to send the server-configured {credential_name} to

Error message

Refusing to send the server-configured {credential_name} to the caller-supplied api_base '{caller_api_base}'. Pass an explicit api_key when overriding api_base for this search provider.

What it means

A credential-exfiltration guard in BaseSearchConfig (litellm/llms/base_llm/search/transformation.py). When a caller overrides api_base for a search provider, LiteLLM refuses to attach a server-managed credential (one configured on the litellm server, e.g. via env/hooks) to the request, unless the caller-supplied base is 'trusted' — i.e. it matches the provider default or the operator's own configured base (checked by _is_trusted_search_api_base). Otherwise it raises ValueError, because honoring a caller-chosen host with a server secret would let any API consumer harvest that secret by pointing api_base at their own server.

Source

Thrown at litellm/llms/base_llm/search/transformation.py:138

        self,
        caller_api_base: str | None,
        default_api_base: str | None,
        base_env_var: str | None,
        credential_name: str,
    ) -> None:
        """
        Block sending a server-managed credential to a caller-chosen host.

        A caller-supplied api_base is honored when constructing the request URL, so
        falling back to a server-configured secret while the caller controls the host
        leaks that secret. The provider default and the operator's own api_base
        override are the only trusted destinations for a server-managed credential.
        """
        if not caller_api_base:
            return
        if _is_trusted_search_api_base(caller_api_base, default_api_base, base_env_var):
            return
        raise ValueError(
            f"Refusing to send the server-configured {credential_name} to the "
            f"caller-supplied api_base '{caller_api_base}'. Pass an explicit api_key "
            f"when overriding api_base for this search provider."
        )

    def resolve_server_api_key(
        self,
        *,
        caller_api_key: str | None,
        caller_api_base: str | None,
        key_env_vars: tuple[str, ...],
        base_env_var: str | None,
        default_api_base: str | None,
    ) -> str | None:
        """
        Resolve a single-secret search API key, falling back to a server-managed
        secret only when the request targets a trusted host.

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Pass an explicit api_key together with the custom api_base: litellm.search(..., api_base="https://my-host", api_key="sk-...") — the guard only blocks server-managed secrets.
  2. Or make the custom base trusted: configure it as the operator-side api_base override (provider settings / base_env_var) rather than passing it per-request.
  3. Or drop the api_base override and use the provider's default endpoint with the server-configured credential.
  4. If you operate the proxy, review whether tenants should be allowed to redirect search traffic at all; this error is the intended security behavior, not a bug.

Example fix

# before
litellm.search(  # server-configured key + caller api_base -> ValueError
    provider="exa", query="litellm",
    api_base="https://search.internal.example",
)

# after
litellm.search(
    provider="exa", query="litellm",
    api_base="https://search.internal.example",
    api_key=os.environ["MY_EXA_KEY"],  # explicit key is allowed
)
Defensive patterns

Strategy: validation

Validate before calling

# caller-side: never rely on a server-managed key with a custom api_base
assert not (api_base and not api_key), "explicit api_key required when overriding api_base"

Type guard

def search_call_is_safe(api_base: str | None, api_key: str | None) -> bool:
    # safe only when: default base, or explicit key supplied with custom base
    return api_base is None or api_key is not None

Try / catch

try:
    litellm.search(provider="exa", query=q, api_base=base)
except ValueError as e:
    if "Refusing to send the server-configured" in str(e):
        raise PermissionError("pass an explicit api_key for custom search api_base") from None
    raise

Prevention

When it happens

Trigger: Calling litellm search/web-search with both (a) an api_base that differs from the provider default/operator-configured base and (b) relying on a server-configured key (no explicit api_key in the call). E.g. litellm.search(..., api_base="https://my-proxy.example/search", key_env_vars resolved server-side).

Common situations: Routing a hosted search provider (Google PSE, Exa, etc.) through an internal gateway by overriding api_base while expecting the litellm server's key to still be used; multi-tenant proxy setups where tenants pass their own api_base; moving a provider to a mirror URL without re-configuring the key.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/9c100d7d217378d1. Report an issue: GitHub.