{"record":{"id":"646728764f07b8b6","repo":"BerriAI/litellm","slug":"openai-moderation-api-key-is-required-set-openai","errorCode":null,"errorMessage":"OpenAI Moderation: api_key is required. Set OPENAI_API_KEY environment variable or pass it in configuration.","messagePattern":"OpenAI Moderation: api_key is required\\. Set OPENAI_API_KEY environment variable or pass it in configuration\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/openai/moderations.py","lineNumber":81,"sourceCode":"            **kwargs,\n        )\n\n        self.async_handler = get_async_httpx_client(llm_provider=httpxSpecialProvider.GuardrailCallback)\n\n        # Store configuration\n        self.api_key = api_key or self._get_api_key()\n        self.api_base = api_base or \"https://api.openai.com/v1\"\n        self.model: Literal[\"omni-moderation-latest\", \"text-moderation-latest\"] = model or \"omni-moderation-latest\"\n\n        # Read by UnifiedLLMGuardrails.async_post_call_streaming_iterator_hook\n        # via getattr(guardrail_to_apply, \"streaming_*\", default).\n        self.streaming_end_of_stream_only: bool = (\n            False if streaming_end_of_stream_only is None else streaming_end_of_stream_only\n        )\n        self.streaming_sampling_rate: int = 5 if streaming_sampling_rate is None else streaming_sampling_rate\n\n        if not self.api_key:\n            raise ValueError(\n                \"OpenAI Moderation: api_key is required. Set OPENAI_API_KEY environment variable or pass it in configuration.\"\n            )\n\n        verbose_proxy_logger.debug(\n            \"Initialized OpenAI Moderation Guardrail: %s with model: %s\", guardrail_name, self.model\n        )\n\n    def _get_api_key(self) -> str | None:\n        \"\"\"Get API key from environment variables or litellm configuration\"\"\"\n        import os\n\n        import litellm\n        from litellm.secret_managers.main import get_secret_str\n\n        return (\n            os.environ.get(\"OPENAI_API_KEY\")\n            or litellm.api_key\n            or litellm.openai_key","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/openai/moderations.py#L63-L99","documentation":"Init-time ValueError from OpenAIModerationGuardrail.__init__: no API key resolved. The guardrail checks the api_key param, then _get_api_key() (which reads OPENAI_API_KEY from the environment and litellm's own key configuration). Since moderations is a paid OpenAI endpoint, the guardrail refuses to construct without credentials.","triggerScenarios":"Configuring guardrail: openai_moderation without api_key in litellm_params while OPENAI_API_KEY is unset in the proxy environment; relying on a generic OPENAI_API_KEY that was only set in the dev shell, not in the deployment; env var set to empty string","commonSituations":"Self-hosted proxy containers missing the OpenAI secret; teams assuming the guardrail reuses a model deployment's key (it does not share it automatically); adding moderation endpoints after initial deployment without updating secret stores","solutions":["Set OPENAI_API_KEY in the proxy's runtime environment (compose env / k8s secret / .env per your deployment)","Or pass api_key explicitly under the guardrail's litellm_params in config.yaml","Verify the key is valid for the moderations API and the account has quota, then restart the proxy"],"exampleFix":"# before\nguardrails:\n  - guardrail_name: oai-moderation\n    litellm_params:\n      guardrail: openai_moderation\n      mode: pre_call\n\n# after (either)\nguardrails:\n  - guardrail_name: oai-moderation\n    litellm_params:\n      guardrail: openai_moderation\n      mode: pre_call\n      api_key: os.environ/OPENAI_API_KEY\n# or export OPENAI_API_KEY=sk-... for the proxy process","handlingStrategy":"validation","validationCode":"import os\n\nif not (os.getenv(\"OPENAI_API_KEY\") or cfg_guardrail_api_key):\n    raise SystemExit(\n        \"openai_moderation guardrail configured but no api_key/OPENAI_API_KEY present\"\n    )","typeGuard":null,"tryCatchPattern":"try:\n    guard = OpenAIModerationGuardrail(guardrail_name=\"mod\", **lp)\nexcept ValueError as e:\n    if \"OPENAI_API_KEY\" in str(e):\n        secrets.load(\"openai\"); guard = OpenAIModerationGuardrail(guardrail_name=\"mod\", **lp)  # retry once after secret mount\n    else:\n        raise","preventionTips":["List guardrail secrets alongside model provider secrets in deployment manifests so they can't drift","Add a startup canary that calls the moderations endpoint once with 'ping' to validate key + quota early"],"tags":["openai-moderation","guardrails","api-key","environment-variables","configuration"],"backgroundTag":"missing-api-key","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}