openai/openai-python · critical · SubjectTokenProviderError

Failed to fetch Azure subject token from IMDS: HTTP {respons

Error message

Failed to fetch Azure subject token from IMDS: HTTP {response.status_code}

What it means

The Azure managed-identity provider queries the Instance Metadata Service (IMDS) at 169.254.169.254 for an access token. If IMDS returns any HTTP error status (response.is_error), the provider raises SubjectTokenProviderError including the status code and attaches the response. Common upstream codes are 404 (wrong resource/identity not available), 429 (IMDS throttling), or 400 (bad request/metadata config).

Source

Thrown at src/openai/auth/_workload.py:146

    def get_token() -> str:
        try:
            url = "http://169.254.169.254/metadata/identity/oauth2/token"
            params: dict[str, str] = {"api-version": api_version, "resource": resource}
            if object_id is not None:
                params["object_id"] = object_id
            if client_id is not None:
                params["client_id"] = client_id
            if msi_res_id is not None:
                params["msi_res_id"] = msi_res_id

            if http_client is not None:
                response = http_client.get(url, params=params, headers={"Metadata": "true"}, timeout=timeout)
            else:
                with httpx2.Client() as client:
                    response = client.get(url, params=params, headers={"Metadata": "true"}, timeout=timeout)

            if response.is_error:
                raise SubjectTokenProviderError(
                    f"Failed to fetch Azure subject token from IMDS: HTTP {response.status_code}",
                    response=response,
                )
            data = response.json()
            token = data.get("access_token")
            if not token:
                raise SubjectTokenProviderError(
                    "Azure IMDS response did not include an access_token", response=response
                )
            return cast(str, token)
        except Exception as e:
            raise SubjectTokenProviderError(f"Failed to fetch Azure subject token from IMDS: {e}") from e

    return {"token_type": "jwt", "get_token": get_token}


def gcp_id_token_provider(
    audience: str = "https://api.openai.com/v1",

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Enable a managed identity (system or user-assigned) on the Azure resource and re-test with curl on the metadata endpoint
  2. Reuse a single OpenAI client instance so IMDS responses (and their tokens) are cached instead of queried per call
  3. Confirm the resource/audience parameter matches what the target API expects
  4. If 429 persists, implement token caching or backoff around provider usage

Example fix

# before
for req in requests_list:
    client = OpenAI(credential=azure_managed_identity_token_provider())  # new IMDS call each time

# after
client = OpenAI(credential=azure_managed_identity_token_provider())  # create once, reuse
for req in requests_list:
    client.chat.completions.create(...)
Defensive patterns

Strategy: retry

Validate before calling

import httpx
r = httpx.get("http://169.254.169.254/metadata/instance", headers={"Metadata":"true"})
assert not r.is_error, r.status_code

Try / catch

for attempt in range(5):
    try:
        return provider_get_token()
    except SubjectTokenProviderError as e:
        if "HTTP 429" in str(e) or "HTTP 50" in str(e): backoff(); continue
        raise

Prevention

When it happens

Trigger: Running with azure_managed_identity_token_provider on an Azure VM/App Service/Functions where IMDS responds with an error: identity not enabled on the resource, throttling (429/limits are ~5 calls/sec with token caching absent), or an unexpected resource URI.

Common situations: System-assigned managed identity not enabled on the VM; hitting IMDS rate limits by creating a new client per request instead of reusing one; wrong resource scope; IMDS temporarily unavailable during VM maintenance.

Related errors


AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28). Data as JSON: /api/errors/285f1139f6273d5f. Report an issue: GitHub.