BerriAI/litellm · error · ValueError
Compresr guardrail api_base {host!r} is a blocked cloud-meta
Error message
Compresr guardrail api_base {host!r} is a blocked cloud-metadata host What it means
ValueError from _validate_api_base: the Compresr guardrail's api_base host (literal or resolved from alternate IP encodings) matches a cloud-metadata endpoint (e.g., 169.254.169.254 and friends in _BLOCKED_METADATA_HOSTS/_BLOCKED_METADATA_IPS). The guardrail intentionally refuses to send request content (which contains user prompts) to link-local metadata services — a guard against SSRF/exfiltration via malicious or mistaken config. The offending host is echoed in {host!r}.
Source
Thrown at litellm/proxy/guardrails/guardrail_hooks/compresr/compresr.py:140
def _validate_api_base(url: str) -> str:
"""Return ``url`` if it passes basic outbound-target checks, else raise.
Best-effort defense in depth for a mis/maliciously-configured ``api_base``:
rejects non-http(s) schemes and cloud-metadata IPs/hosts (incl. alternate IP
encodings); private ranges are allowed for on-prem deployments. NOT a complete
SSRF control — no DNS resolution, and the shared client follows redirects and
re-resolves DNS (TOCTOU / rebinding); ``api_base`` is trusted operator config,
so this is an accepted limitation.
"""
parsed: Final = urlparse(url)
if parsed.scheme not in ("http", "https"):
raise ValueError(f"Compresr guardrail api_base must be http or https, got scheme={parsed.scheme!r}")
host: Final = (parsed.hostname or "").lower()
if not host:
raise ValueError("Compresr guardrail api_base has no host")
ip_literal: Final = _parse_ip_literal(host)
if host in _BLOCKED_METADATA_HOSTS or (ip_literal is not None and ip_literal in _BLOCKED_METADATA_IPS):
raise ValueError(f"Compresr guardrail api_base {host!r} is a blocked cloud-metadata host")
return url
def _is_str_object_dict(value: object) -> TypeGuard[dict[str, object]]: # guard-ok: isinstance narrows correctly; predicate is trivially correct # fmt: skip
return isinstance(value, dict)
def _is_object_list(value: object) -> TypeGuard[list[object]]: # guard-ok: isinstance narrows correctly; predicate is trivially correct # fmt: skip
return isinstance(value, list)
def _replace_text_in_content(content: object, new_text: str) -> object:
"""Write ``new_text`` back into a ``content`` value, preserving shape.
``str`` content is replaced directly. An all-text part list collapses to a
single part carrying the last declared cache_control breakpoint. Anything
else is returned unchanged: breakpoints are positional, so one compressed
string cannot be written back across a non-text part without moving textView on GitHub (pinned to 77b7c6c40c)
Solutions
- Point api_base at the real Compresr service host, never at link-local/metadata addresses.
- Audit how the api_base value got into the config — if you didn't set it, treat it as a compromise indicator and investigate config provenance.
- Re-run with a corrected COMPRESR_API_BASE / api_key setup and restart the proxy.
Example fix
# before — blocked metadata target litellm_params: guardrail: compresr api_base: http://169.254.169.254/latest/meta-data # after litellm_params: guardrail: compresr api_base: https://compresr.mycompany.internal
Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
import ipaddress
METADATA = {"169.254.169.254", "metadata.google.internal"}
def rejects_metadata(url: str) -> bool:
host = (urlparse(url).hostname or "").lower()
try:
ip = ipaddress.ip_address(host)
return ip.is_link_local or str(ip) in METADATA or host in METADATA
except ValueError:
return host in METADATA
assert not rejects_metadata(api_base), f"api_base targets cloud metadata: {api_base}" Prevention
- Treat config-provenance seriously: only trusted CI may modify guardrail api_base values.
- Add config-lint rules that reject link-local (169.254.0.0/16, fe80::/10) and well-known metadata hosts.
- If this error appears unexpectedly, investigate as a potential supply-chain/config compromise, not just a typo.
When it happens
Trigger: api_base set (deliberately or via compromise of config) to http://169.254.169.254/..., http://metadata.google.internal, alternate encodings like decimal/hex IP forms of 169.254.169.254, or [fd00:ec2::254] style metadata IPs — _parse_ip_literal normalizes encodings before matching.
Common situations: Security testing/red-team configs probing whether the proxy will leak prompts to the instance-metadata service; misconfigured internal service discovery returning the metadata IP; penetration-test findings where this block correctly fires.
Related errors
- Compresr guardrail api_base must be http or https, got schem
- Compresr guardrail api_base has no host
- Compresr guardrail requires an API key. Set `api_key` in the
- max_bytes_per_call must be >= 0 (0 disables the cap; positiv
- Bedrock guardrail failed: {e}
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/554d2f8931c24c85.
Report an issue: GitHub.