openai/openai-python · error · ValueError

Expected `azure_ad_token_provider` argument to return a non-

Error message

Expected `azure_ad_token_provider` argument to return a non-empty string.

What it means

The sync Azure client invokes your azure_ad_token_provider callable before each request and requires it to return a non-empty string. It raises ValueError if the callable returns None, an empty string, or any non-string value.

Source

Thrown at src/openai/lib/azure.py:451

                "azure_ad_token_provider": azure_ad_token_provider,
                **_extra_kwargs,
            },
        )

    with_options = copy

    def _get_azure_ad_token(self) -> str | None:
        if self._azure_ad_token is not None:
            return self._azure_ad_token

        provider = self._azure_ad_token_provider
        if provider is not None:
            token = cast(object, provider())
            if isinstance(token, str):
                # Bypass subclass methods before validating or interpolating credentials.
                token = str.__str__(token)
            if not isinstance(token, str) or not token:
                raise ValueError("Expected `azure_ad_token_provider` argument to return a non-empty string.")
            return token

        return None

    @override
    def _auth_headers(self, security: SecurityOptions) -> dict[str, str]:  # noqa: ARG002
        if self._azure_ad_token is not None:
            return {"Authorization": f"Bearer {self._azure_ad_token}"}

        if self.api_key and self.api_key != API_KEY_SENTINEL:
            return {"api-key": self.api_key}

        return {}

    @override
    def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None:
        if _has_auth_header(headers) or _has_auth_header(custom_headers):
            return

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Make the provider raise on failure instead of returning None/empty
  2. Verify DefaultAzureCredential can actually acquire a token in that environment (az login, managed identity, env vars)
  3. Return the plain str token: lambda: str(token)

Example fix

# before
client = AzureOpenAI(azure_ad_token_provider=lambda: "")
# after
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
client = AzureOpenAI(azure_ad_token_provider=get_bearer_token_provider(DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default"))
Defensive patterns

Strategy: validation

Validate before calling

def safe_provider():
    token = raw_provider()
    if not isinstance(token, str) or not token:
        raise RuntimeError("token provider failed to yield a token")
    return token
client = AzureOpenAI(azure_ad_token_provider=safe_provider)

Type guard

def is_valid_token(t) -> bool:
    return isinstance(t, str) and len(t) > 0

Try / catch

try:
    resp = client.chat.completions.create(...)
except ValueError as e:
    if "azure_ad_token_provider" in str(e):
        refresh_credentials(); retry()
    raise

Prevention

When it happens

Trigger: Passing azure_ad_token_provider=lambda: None, a function whose credential lookup fails silently and returns empty, or one that returns bytes/an object instead of str.

Common situations: Using azure.identity DefaultAzureCredential token providers in an environment where the credential is unauthenticated; cached token helpers returning '' after expiry; providers with buggy string handling (str subclass bypass is attempted first).

Related errors


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