BerriAI/litellm · error · AzureSpeechAudioTranscriptionException
Azure AI Speech transcription requires a Cognitive Services
Error message
Azure AI Speech transcription requires a Cognitive Services or STT Speech endpoint, not an Azure OpenAI endpoint.
What it means
LiteLLM resolves the Azure Speech base URL from the hostname of your `api_base`. If the hostname is recognized as an Azure OpenAI endpoint (e.g. <resource>.openai.azure.com) it raises this 400, because Azure AI Speech transcription calls the Speech/Cognitive Services API, not the Azure OpenAI audio API. This guard prevents a guaranteed-to-fail request (wrong API surface, wrong auth header).
Source
Thrown at litellm/llms/azure/audio_transcription/transformation.py:163
message=error_message,
status_code=status_code,
headers=headers,
)
def _resolve_stt_base_url(self, api_base: str) -> str:
api_base = api_base.rstrip("/")
parsed_url: Final = urlparse(api_base)
hostname: Final = parsed_url.hostname or ""
if self._is_cognitive_services_endpoint(hostname=hostname):
region: Final = self._extract_region_from_hostname(hostname=hostname, domain=self.COGNITIVE_SERVICES_DOMAIN)
return self._build_stt_base_url(region=region)
if self._is_stt_endpoint(hostname=hostname):
return f"{parsed_url.scheme}://{hostname}"
if self._is_azure_openai_endpoint(hostname=hostname):
raise AzureSpeechAudioTranscriptionException(
message=(
"Azure AI Speech transcription requires a Cognitive Services "
"or STT Speech endpoint, not an Azure OpenAI endpoint."
),
status_code=400,
)
return api_base
def _is_cognitive_services_endpoint(self, hostname: str) -> bool:
return hostname == self.COGNITIVE_SERVICES_DOMAIN or hostname.endswith(f".{self.COGNITIVE_SERVICES_DOMAIN}")
def _is_stt_endpoint(self, hostname: str) -> bool:
return hostname == self.STT_SPEECH_DOMAIN or hostname.endswith(f".{self.STT_SPEECH_DOMAIN}")
def _is_azure_openai_endpoint(self, hostname: str) -> bool:
return hostname.endswith(".openai.azure.com")
View on GitHub (pinned to 6c2dcb801b)
Solutions
- Switch api_base to your Speech resource endpoint: https://{region}.api.cognitive.microsoft.com or https://{region}.stt.speech.microsoft.com.
- If you actually want Azure OpenAI Whisper, use an azure/ deployment model name routed to Azure OpenAI instead of the Azure Speech integration.
- Create a Speech resource in the Azure portal if none exists and copy its endpoint.
Example fix
# before litellm.transcription(model='azure/speech', file=f, api_base='https://myres.openai.azure.com', api_key=key) # after litellm.transcription(model='azure/speech', file=f, api_base='https://eastus.api.cognitive.microsoft.com', api_key=key)
Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
host = urlparse(api_base).hostname or ''
if host.endswith('openai.azure.com'):
raise ValueError(f'{api_base} is an Azure OpenAI endpoint; use a Cognitive Services/STT endpoint for Speech transcription.') Prevention
- Keep separate config keys for Azure OpenAI endpoints and Speech endpoints.
- Add a config lint rule rejecting '*.openai.azure.com' values for speech models.
When it happens
Trigger: Passing api_base='https://myresource.openai.azure.com' (copied from an existing Azure OpenAI deployment) to a transcription call routed through the Azure Speech handler.
Common situations: Teams with existing Azure OpenAI deployments reuse that endpoint for transcription out of habit; config templates for Azure OpenAI chat are duplicated for speech without changing the endpoint; confusion because Azure OpenAI also offers whisper audio APIs.
Related errors
- api_base is required for Azure AI Speech transcription. Use
- prompt_characters must be provided for tts calls. prompt_cha
- model is required
- input is required
- AzureException ContextWindowExceededError - {message}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/6bb645ebf3fe06bc.
Report an issue: GitHub.