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
- 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.
- 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.
- Or drop the api_base override and use the provider's default endpoint with the server-configured credential.
- 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
- Treat api_base overrides as untrusted combinations: always pair them with an explicit api_key.
- Configure operator-level api_base overrides in litellm config instead of per-request when the server credential must be used.
- Never attempt to bypass this guard; it exists to prevent secret exfiltration by API callers.
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
- api_base is required
- api_base is required
- api_base is required
- api_base is required
- api_base is required
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/9c100d7d217378d1.
Report an issue: GitHub.