{"record":{"id":"1b0624bdc7b67b53","repo":"microsoft/semantic-kernel","slug":"failed-to-get-ephemeral-token-error-text-1b0624","errorCode":null,"errorMessage":"Failed to get ephemeral token: {error_text}","messagePattern":"Failed to get ephemeral token: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/ai/open_ai/services/azure_realtime.py","lineNumber":367,"sourceCode":"        OpenAI's {\"client_secret\": {\"value\": \"...\"}}.\n        See: https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/realtime-audio-webrtc\n        \"\"\"\n        data = {\n            \"session\": {\n                \"type\": \"realtime\",\n                \"model\": self.ai_model_id,\n            }\n        }\n        headers, url = self._get_ephemeral_token_headers_and_url()\n        headers = prepend_semantic_kernel_to_user_agent(headers)\n        try:\n            async with (\n                ClientSession() as session,\n                session.post(url, headers=headers, json=data) as response,\n            ):\n                if response.status not in [200, 201]:\n                    error_text = await response.text()\n                    raise Exception(f\"Failed to get ephemeral token: {error_text}\")\n\n                result = await response.json()\n                # Azure GA format returns {\"value\": \"token\"} directly\n                return result[\"value\"]\n\n        except Exception as e:\n            logger.error(f\"Failed to get ephemeral token: {e!s}\")\n            raise\n\n    @override\n    def _get_webrtc_url(self) -> str:\n        \"\"\"Get the WebRTC URL.\n\n        Uses the GA endpoint format: /openai/v1/realtime/calls\n        See: https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/realtime-audio-webrtc\n        \"\"\"\n        endpoint = str(self.client._base_url).rstrip(\"/\")  # type: ignore[attr-defined]\n        if \"/openai\" in endpoint:","sourceCodeStart":349,"sourceCodeEnd":385,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/ai/open_ai/services/azure_realtime.py#L349-L385","documentation":"Raised inside AzureRealtimeWebRTC._get_ephemeral_token when the HTTP POST to the Azure Realtime client_secrets endpoint returns a status code outside [200, 201]. The response body text is captured as error_text and interpolated into the message. This is a runtime/network error distinct from initialization errors — it fires during session setup, not construction. The exception is logged via logger.error and re-raised.","triggerScenarios":"Calling _get_ephemeral_token (typically during WebRTC session creation) when the Azure endpoint returns an error: 401/403 (invalid or expired credentials), 404 (deployment not found or realtime not enabled for the resource), 429 (rate limit), or 5xx (Azure service error). The error_text contains Azure's JSON error response body.","commonSituations":"Expired Azure AD token used for the request; deployment name does not match an actual deployment in the Azure resource; realtime API not enabled in the subscription/region; API key was rotated and the old one is now invalid; transient Azure outage or throttling.","solutions":["Read the full error_text in the exception message — it contains Azure's JSON error body with the specific failure reason (e.g. 'DeploymentNotFound', 'accessDenied').","Verify the deployment name matches a deployment configured for the Realtime API in Azure Portal.","If using an AD token, ensure it has not expired — tokens typically last ~1 hour; refresh and reconstruct if needed.","For 429 responses, implement exponential backoff retry on the session creation call.","Confirm the Azure resource is in a region that supports the Realtime API."],"exampleFix":"# before — no error handling around session creation\nawait service.create_session(chat_history=history)\n\n# after — catch and inspect the error, retry on transient failures\nimport asyncio\nfrom semantic_kernel.exceptions.service_exceptions import ServiceInitializationError\n\nfor attempt in range(3):\n    try:\n        await service.create_session(chat_history=history)\n        break\n    except Exception as e:\n        if '429' in str(e) and attempt < 2:\n            await asyncio.sleep(2 ** attempt)\n            continue\n        raise","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"import asyncio\nimport logging\n\nlogger = logging.getLogger(__name__)\n\nasync def create_realtime_session_with_retry(service, chat_history=None, max_retries=3):\n    for attempt in range(max_retries):\n        try:\n            await service.create_session(chat_history=chat_history)\n            return\n        except Exception as e:\n            error_msg = str(e)\n            # Parse Azure error status from the interpolated message\n            if '429' in error_msg and attempt < max_retries - 1:\n                wait = 2 ** attempt\n                logger.warning(f'Rate limited, retrying in {wait}s (attempt {attempt + 1})')\n                await asyncio.sleep(wait)\n                continue\n            if '5' in error_msg[:1] and attempt < max_retries - 1:\n                await asyncio.sleep(2 ** attempt)\n                continue\n            logger.error(f'Failed to get ephemeral token: {error_msg}')\n            raise","preventionTips":["Inspect the error_text in the exception message — it contains Azure's JSON error body with the specific reason.","Verify the deployment name matches an existing realtime-enabled deployment before session creation.","Ensure AD tokens are fresh — refresh if they are near expiry (typically ~1 hour lifetime).","Implement exponential backoff for 429 (rate limit) responses.","Confirm the Azure resource region supports the Realtime API."],"tags":["azure-openai","realtime","webrtc","ephemeral-token","network","runtime"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}