BerriAI/litellm · error · ValueError
Missing CLOUDFLARE_ACCOUNT_ID - set CLOUDFLARE_ACCOUNT_ID in
Error message
Missing CLOUDFLARE_ACCOUNT_ID - set CLOUDFLARE_ACCOUNT_ID in the environment or pass api_base explicitly
What it means
LiteLLM's Cloudflare Workers AI adapter builds the OpenAI-compatible endpoint URL from your Cloudflare account ID. When no api_base is passed and the CLOUDFLARE_ACCOUNT_ID environment variable is unset (or empty, which normalize_nonempty_secret_str treats as missing), _resolve_api_base raises this ValueError before any HTTP request is made. The account ID is required to construct 'https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1'.
Source
Thrown at litellm/llms/cloudflare/chat/transformation.py:53
optional_params: dict,
litellm_params: dict,
stream: bool | None = None,
) -> str:
return super().get_complete_url(
api_base=self._resolve_api_base(api_base),
api_key=api_key,
model=model,
optional_params=optional_params,
litellm_params=litellm_params,
stream=stream,
)
@staticmethod
def _resolve_api_base(api_base: str | None) -> str:
if not api_base:
account_id: Final = normalize_nonempty_secret_str(get_secret_str("CLOUDFLARE_ACCOUNT_ID"))
if account_id is None:
raise ValueError(
"Missing CLOUDFLARE_ACCOUNT_ID - set CLOUDFLARE_ACCOUNT_ID in the environment or pass api_base explicitly"
)
return f"https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/v1"
trimmed: Final = api_base.rstrip("/")
if trimmed.endswith("/ai/run"):
verbose_logger.warning(
"Cloudflare api_base ending in '/ai/run' is the legacy Workers AI path and no longer serves OpenAI-compatible requests; rewriting to the '/ai/v1' endpoint"
)
return f"{trimmed[: -len('/ai/run')]}/ai/v1"
return api_base
def validate_environment(
self,
headers: dict,
model: str,
messages: list[AllMessageValues],
optional_params: dict,
litellm_params: dict,View on GitHub (pinned to 6c2dcb801b)
Solutions
- Export CLOUDFLARE_ACCOUNT_ID (your 32-hex-char Cloudflare account ID, visible in the Cloudflare dashboard URL) in the environment running LiteLLM.
- Alternatively pass api_base explicitly, e.g. api_base='https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai/v1'.
- If using a .env file, confirm it is actually loaded (python-dotenv load_dotenv(), docker env_file, etc.) and that the variable name has no typos.
- Verify with a quick check: python -c "import os; print(os.environ.get('CLOUDFLARE_ACCOUNT_ID'))" before starting the app.
Example fix
# before
os.environ.pop("CLOUDFLARE_ACCOUNT_ID", None)
response = litellm.completion(model="cloudflare/@cf/meta/llama-3.1-8b-instruct", messages=[...])
# after
os.environ["CLOUDFLARE_ACCOUNT_ID"] = "abc123..." # from Cloudflare dashboard
response = litellm.completion(model="cloudflare/@cf/meta/llama-3.1-8b-instruct", messages=[...]) Defensive patterns
Strategy: validation
Validate before calling
import os
account_id = os.environ.get("CLOUDFLARE_ACCOUNT_ID", "").strip()
if not account_id:
raise SystemExit("Set CLOUDFLARE_ACCOUNT_ID or pass api_base before calling cloudflare models") Try / catch
try:
resp = litellm.completion(model="cloudflare/@cf/meta/llama-3.1-8b-instruct", messages=msgs)
except ValueError as e:
if "CLOUDFLARE_ACCOUNT_ID" in str(e):
# config problem: fail fast with actionable message, do not retry
raise Prevention
- Centralize provider config in one bootstrap module that asserts required env vars at startup.
- Add a startup health check listing all provider env vars (CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_KEY) before serving traffic.
- Store the account ID next to the API key in your secret manager so they are provisioned together.
When it happens
Trigger: Calling litellm.completion(model='cloudflare/...', ...) (or the async equivalent) without api_base while CLOUDFLARE_ACCOUNT_ID is not exported in the process environment; setting CLOUDFLARE_ACCOUNT_ID='' or to a whitespace-only string is also treated as missing.
Common situations: Deploying to a new environment (container, CI, serverless) where the Cloudflare env vars were not migrated; using a .env file that is not loaded by the runtime; passing only CLOUDFLARE_API_KEY and assuming the account ID is inferred from it.
Related errors
- API base is required for OpenAI image variations
- API base is required for Topaz image variations
- AZURE_SENTINEL_DCR_IMMUTABLE_ID is required. Set it as an en
- AZURE_SENTINEL_ENDPOINT is required. Set it as an environmen
- AZURE_SENTINEL_TENANT_ID or AZURE_TENANT_ID is required. Set
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/a614c42d736e7939.
Report an issue: GitHub.