{"record":{"id":"c15d931f5629b00c","repo":"deepset-ai/haystack","slug":"please-provide-an-api-key-or-an-azure-active-direc-c15d93","errorCode":null,"errorMessage":"Please provide an API key or an Azure Active Directory token.","messagePattern":"Please provide an API key or an Azure Active Directory token\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"haystack/components/generators/chat/azure.py","lineNumber":213,"sourceCode":"        \"\"\"\n        # We intentionally do not call super().__init__ here because we only need to instantiate the client to interact\n        # with the API.\n\n        # Why is this here?\n        # AzureOpenAI init is forcing us to use an init method that takes either base_url or azure_endpoint as not\n        # None init parameters. This way we accommodate the use case where env var AZURE_OPENAI_ENDPOINT is set instead\n        # of passing it as a parameter.\n        azure_endpoint = azure_endpoint or os.environ.get(\"AZURE_OPENAI_ENDPOINT\")\n        # `azure_endpoint` accepts either a plain string or a `Secret`. We keep the original value on the instance for\n        # serialization and resolve it to a string only to validate that an endpoint was provided.\n        resolved_azure_endpoint = (\n            azure_endpoint.resolve_value() if isinstance(azure_endpoint, Secret) else azure_endpoint\n        )\n        if not resolved_azure_endpoint:\n            raise ValueError(\"Please provide an Azure endpoint or set the environment variable AZURE_OPENAI_ENDPOINT.\")\n\n        if api_key is None and azure_ad_token is None:\n            raise ValueError(\"Please provide an API key or an Azure Active Directory token.\")\n\n        # The check above makes mypy incorrectly infer that api_key is never None,\n        # which propagates the incorrect type.\n        self.api_key = api_key  # type: ignore\n        self.azure_ad_token = azure_ad_token\n        self.generation_kwargs = generation_kwargs or {}\n        self.streaming_callback = streaming_callback\n        self.api_version = api_version\n        self.azure_endpoint = azure_endpoint\n        self.azure_deployment = azure_deployment\n        self.organization = organization\n        self.model = azure_deployment or \"gpt-4.1-mini\"\n        self.timeout = timeout\n        self.max_retries = max_retries\n        self.default_headers = default_headers or {}\n        self.azure_ad_token_provider = azure_ad_token_provider\n        self.http_client_kwargs = http_client_kwargs\n        _check_duplicate_tool_names(flatten_tools_or_toolsets(tools))","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/components/generators/chat/azure.py#L195-L231","documentation":"AzureOpenAIChatGenerator requires credentials: either an API key or an Azure Active Directory token must be supplied. If both api_key and azure_ad_token are None, __init__ raises ValueError.","triggerScenarios":"Constructing AzureOpenAIChatGenerator() with no api_key/azure_ad_token and with AZURE_OPENAI_API_KEY and AZURE_OPENAI_AD_TOKEN env vars both unset or resolving to None.","commonSituations":"Forgetting to deploy the .env/secrets in production or CI; using default Secret resolution but never exporting the env vars; switching to AAD auth but passing neither token nor key.","solutions":["Pass api_key=Secret.from_env_var(\"AZURE_OPENAI_API_KEY\") explicitly or set the AZURE_OPENAI_API_KEY environment variable","For AAD/Entra auth, pass azure_ad_token (or set AZURE_OPENAI_AD_TOKEN) obtained via azure.identity DefaultAzureCredential","Confirm secrets are mounted/loaded in the deployment environment (kubectl secret, CI secrets, .env loading)"],"exampleFix":"// before\ngenerator = AzureOpenAIChatGenerator(azure_endpoint=\"https://my.openai.azure.com/\")  # no credentials\n// after\nfrom haystack.utils import Secret\ngenerator = AzureOpenAIChatGenerator(\n    azure_endpoint=\"https://my.openai.azure.com/\",\n    api_key=Secret.from_env_var(\"AZURE_OPENAI_API_KEY\"),\n)","handlingStrategy":"validation","validationCode":"import os\nif not os.getenv(\"AZURE_OPENAI_API_KEY\") and not os.getenv(\"AZURE_OPENAI_AD_TOKEN\"):\n    raise ValueError(\"Provide AZURE_OPENAI_API_KEY or AZURE_OPENAI_AD_TOKEN\")","typeGuard":null,"tryCatchPattern":"try:\n    generator = AzureOpenAIChatGenerator(api_key=Secret.from_env_var(\"AZURE_OPENAI_API_KEY\"))\nexcept ValueError as e:\n    logger.error(\"Missing Azure credentials: %s\", e)\n    raise","preventionTips":["Always use Secret.from_env_var so resolution errors surface with clear messages","For AAD auth, obtain a token via azure.identity and pass it as azure_ad_token","Verify secrets exist in the deployment environment before pipeline startup (fail-fast check)"],"tags":["azure","authentication","missing-credentials"],"backgroundTag":"missing-api-key","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}