BerriAI/litellm · error · AzureSpeechAudioTranscriptionException

api_key is required for Azure AI Speech transcription.

Error message

api_key is required for Azure AI Speech transcription.

What it means

LiteLLM's Azure AI Speech transcription handler requires an API key before it can build request headers. The key is passed as the `api_key` argument or read from the AZURE_SPEECH_API_KEY environment variable; if neither is set, this 401 error is raised before any network call happens. The key is sent as the `Ocp-Apim-Subscription-Key` header to the Azure Speech endpoint.

Source

Thrown at litellm/llms/azure/audio_transcription/transformation.py:72

        supported_params: Final = self.get_supported_openai_params(model=model)
        for key, value in non_default_params.items():
            if key in supported_params:
                optional_params[key] = value
        return optional_params

    def validate_environment(
        self,
        headers: dict,
        model: str,
        messages: list[AllMessageValues],
        optional_params: dict,
        litellm_params: dict,
        api_key: str | None = None,
        api_base: str | None = None,
    ) -> dict:
        api_key = api_key or get_secret_str("AZURE_SPEECH_API_KEY")
        if not api_key:
            raise AzureSpeechAudioTranscriptionException(
                message="api_key is required for Azure AI Speech transcription.",
                status_code=401,
            )

        validated_headers: Final = headers.copy()
        validated_headers["Ocp-Apim-Subscription-Key"] = api_key
        validated_headers["Content-Type"] = validated_headers.get("Content-Type", "audio/wav")
        validated_headers["Accept"] = "application/json"
        return validated_headers

    def get_complete_url(
        self,
        api_base: str | None,
        api_key: str | None,
        model: str,
        optional_params: dict,
        litellm_params: dict,
        stream: bool | None = None,

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Set AZURE_SPEECH_API_KEY in the environment: export AZURE_SPEECH_API_KEY=<your Cognitive Services key>.
  2. Or pass the key explicitly: litellm.transcription(model=..., api_key=<key>, api_base=<endpoint>).
  3. If using the LiteLLM proxy, add api_key to the model's deployment config in config.yaml.
  4. Verify with a quick check that the variable is visible to the same process running LiteLLM (printenv AZURE_SPEECH_API_KEY).

Example fix

// before
litellm.transcription(model='azure/whisper', file=open('a.wav','rb'), api_base='https://eastus.stt.speech.microsoft.com')

// after
litellm.transcription(model='azure/whisper', file=open('a.wav','rb'), api_base='https://eastus.stt.speech.microsoft.com', api_key=os.environ['AZURE_SPEECH_API_KEY'])
Defensive patterns

Strategy: validation

Validate before calling

import os

key = os.environ.get('AZURE_SPEECH_API_KEY')
if not key:
    raise RuntimeError('Set AZURE_SPEECH_API_KEY or pass api_key before calling Azure Speech transcription.')

Prevention

When it happens

Trigger: Calling `litellm.transcription(model='azure/...', ...)` (or the /v1/audio/transcriptions proxy route with an Azure Speech model) without an `api_key` parameter while AZURE_SPEECH_API_KEY is unset in the process environment.

Common situations: Working locally with the key in a .env file that was never loaded; deploying behind a proxy where the key was configured under AZURE_API_KEY (Azure OpenAI) instead of AZURE_SPEECH_API_KEY; rotating secrets and the new variable name differing.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/59aefb3363e5745c. Report an issue: GitHub.