{"record":{"id":"3c72b79a210fe6d6","repo":"BerriAI/litellm","slug":"missing-cloudflare-api-key-a-call-is-being-made","errorCode":null,"errorMessage":"Missing Cloudflare API Key - A call is being made to cloudflare but no key is set either in the environment variables or via params","messagePattern":"Missing Cloudflare API Key - A call is being made to cloudflare but no key is set either in the environment variables or via params","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/cloudflare/chat/transformation.py","lineNumber":76,"sourceCode":"        if trimmed.endswith(\"/ai/run\"):\n            verbose_logger.warning(\n                \"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\"\n            )\n            return f\"{trimmed[: -len('/ai/run')]}/ai/v1\"\n        return api_base\n\n    def validate_environment(\n        self,\n        headers: dict,\n        model: str,\n        messages: list[AllMessageValues],\n        optional_params: dict,\n        litellm_params: dict,\n        api_key: str | None = None,\n        api_base: str | None = None,\n    ) -> dict:\n        if api_key is None:\n            raise ValueError(\n                \"Missing Cloudflare API Key - A call is being made to cloudflare but no key is set either in the environment variables or via params\"\n            )\n        return super().validate_environment(\n            headers=headers,\n            model=model,\n            messages=messages,\n            optional_params=optional_params,\n            litellm_params=litellm_params,\n            api_key=api_key,\n            api_base=api_base,\n        )\n\n    def get_error_class(self, error_message: str, status_code: int, headers: dict | httpx.Headers) -> BaseLLMException:\n        return CloudflareError(\n            status_code=status_code,\n            message=error_message,\n        )\n","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/cloudflare/chat/transformation.py#L58-L94","documentation":"The Cloudflare transformation's validate_environment refuses to proceed when api_key is None. LiteLLM normally resolves the key from CLOUDFLARE_API_KEY (or provider-specific params) before reaching this point, so this ValueError means no credential could be found anywhere for the cloudflare provider. No HTTP call is attempted.","triggerScenarios":"Invoking a cloudflare/* model with neither CLOUDFLARE_API_KEY set in the environment nor api_key=... passed to the completion call; also triggered when the key is set but resolved to None (e.g. empty string handled upstream as unset).","commonSituations":"Missing CLOUDFLARE_API_KEY in deployment environments; rotating/renaming keys and forgetting this provider; assuming the generic OPENAI_API_KEY style fallback covers Cloudflare when only the account ID was configured.","solutions":["Set CLOUDFLARE_API_KEY in the environment with a valid Cloudflare API token (AI/Workers AI permissions enabled).","Or pass the key per-call: litellm.completion(model='cloudflare/...', messages=[...], api_key='<token>').","If using the LiteLLM proxy, add cloudflare to the environment_variables block in the config YAML.","Confirm the token has the 'Workers AI' read permission in the Cloudflare dashboard, otherwise you will trade this error for a 403 next."],"exampleFix":"# before\nresponse = litellm.completion(model=\"cloudflare/@cf/meta/llama-3.1-8b-instruct\", messages=[...])\n\n# after\nresponse = litellm.completion(\n    model=\"cloudflare/@cf/meta/llama-3.1-8b-instruct\",\n    messages=[...],\n    api_key=os.environ[\"CLOUDFLARE_API_KEY\"],\n)","handlingStrategy":"validation","validationCode":"import os\n\napi_key = os.environ.get(\"CLOUDFLARE_API_KEY\") or os.environ.get(\"CLOUDFLARE_API_TOKEN\")\nif not api_key:\n    raise SystemExit(\"Set CLOUDFLARE_API_KEY before calling cloudflare models\")","typeGuard":null,"tryCatchPattern":"try:\n    resp = litellm.completion(model=\"cloudflare/...\", messages=msgs, api_key=api_key)\nexcept ValueError as e:\n    if \"Missing Cloudflare API Key\" in str(e):\n        raise RuntimeError(\"Cloudflare credentials not configured\") from e\n    raise","preventionTips":["Pass api_key explicitly from your secret manager instead of relying on ambient env vars.","Include Cloudflare credentials in deployment checklists and smoke tests (one tiny completion call at deploy time).","Use a config validator (pydantic Settings) that requires the key when the app enables cloudflare models."],"tags":["cloudflare","authentication","api-key","configuration"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}