openai/openai-python · critical · SubjectTokenProviderError

The token file at {token_file_path} is empty.

Error message

The token file at {token_file_path} is empty.

What it means

Part of the workload-identity (Kubernetes service account) token provider: it reads the projected service-account token file and treats an empty-or-whitespace-only file as a hard error. This means the token volume was mounted but the kubelet never projected a token into it (or it was truncated), so workload identity authentication cannot proceed.

Source

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

def k8s_service_account_token_provider(
    token_file_path: str | Path = "/var/run/secrets/kubernetes.io/serviceaccount/token",
) -> SubjectTokenProvider:
    """
    Get a subject token provider for Kubernetes clusters with Workload Identity configured.

    Cloud providers typically mount the subject token as a file in the container.

    Args:
        token_file_path: path to the mounted service account token file. Defaults to `/var/run/secrets/kubernetes.io/serviceaccount/token`.
    """

    def get_token() -> str:
        try:
            with open(token_file_path, "r") as f:
                token = f.read().strip()
                if not token:
                    raise SubjectTokenProviderError(f"The token file at {token_file_path} is empty.")
                return token
        except Exception as e:
            raise SubjectTokenProviderError(f"Failed to read the token file at {token_file_path}: {e}") from e

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


def azure_managed_identity_token_provider(
    resource: str = "https://management.azure.com/",
    *,
    object_id: str | None = None,
    client_id: str | None = None,
    msi_res_id: str | None = None,
    api_version: str = "2018-02-01",
    timeout: float = 10.0,
    http_client: httpx2.Client | None = None,
) -> SubjectTokenProvider:
    """

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Verify the file has content: kubectl exec ... -- cat <path>; fix the projected volume configuration
  2. Add a startup wait/retry until the token file is non-empty before creating the client
  3. Correct the token file path to the actual projected token location (/var/run/secrets/tokens/... or the kubelet default)
  4. If not on Kubernetes with projected tokens, switch to another credential type

Example fix

# before
client = OpenAI(credential="workload")  # token file empty at startup

# after
import time
from openai.auth import k8s_service_account_token_provider  # adjust to actual API
for _ in range(30):
    if open(TOKEN_PATH).read().strip(): break
    time.sleep(1)
client = OpenAI(credential=k8s_service_account_token_provider(TOKEN_PATH))
Defensive patterns

Strategy: validation

Validate before calling

with open(TOKEN_PATH) as f:
    token = f.read().strip()
if not token:
    wait_for_token_projection()

Type guard

def token_file_ready(path: str) -> bool:
    import os
    try:
        return bool(open(path).read().strip())
    except OSError:
        return False

Try / catch

try:
    client.chat.completions.create(...)
except SubjectTokenProviderError as e:
    if "is empty" in str(e): wait_and_reinit_client()

Prevention

When it happens

Trigger: Running with credential='workload' (or the k8s workload identity flow) where the token file referenced by the provider config exists but is empty — misconfigured projected volume, race at pod startup before token projection, or a manually created empty file.

Common situations: Kubernetes projected service-account token volumes not yet populated at startup; wrong file path pointing at an empty mounted file; using workload identity outside a properly configured cluster; CI containers faking the token file.

Related errors


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