openai/openai-python · error · OpenAIError

Invalid `workload_identity` configuration: expected an X.509

Error message

Invalid `workload_identity` configuration: expected an X.509 or subject-token identity

What it means

The `workload_identity` argument must be a dict containing either an X.509 identity (keys like `certificate_source_path`/private key material) or a `"provider"` key for a subject-token identity. Any other shape — missing keys, wrong type, partial dicts — raises this OpenAIError at construction.

Source

Thrown at src/openai/_client.py:297

        self.project = project

        if webhook_secret is None:
            webhook_secret = os.environ.get("OPENAI_WEBHOOK_SECRET")
        self.webhook_secret = webhook_secret

        self.websocket_base_url = websocket_base_url

        if is_x509_workload_identity(workload_identity):
            x509_identity = workload_identity
            subject_token_identity = None
        elif workload_identity is None:
            x509_identity = None
            subject_token_identity = None
        elif "provider" in workload_identity:
            x509_identity = None
            subject_token_identity = workload_identity
        else:
            raise OpenAIError("Invalid `workload_identity` configuration: expected an X.509 or subject-token identity")
        if provider_runtime is not None:
            base_url = provider_runtime.base_url
        elif base_url is None:
            base_url = os.environ.get("OPENAI_BASE_URL")
        self._base_url_was_default = provider_runtime is None and base_url is None
        self._data_residency = data_residency
        if base_url is None:
            base_url = MTLS_API_BASE_URL if x509_identity is not None else "https://api.openai.com/v1"
        if x509_identity is not None:
            validate_x509_api_url(base_url)

        self._ambient_authorizations = frozenset()
        custom_headers_env = os.environ.get("OPENAI_CUSTOM_HEADERS") if provider_runtime is None else None
        if custom_headers_env is not None:
            parsed: dict[str, str] = {}
            for line in custom_headers_env.split("\n"):
                colon = line.find(":")
                if colon >= 0:

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Use a documented X.509 shape: `workload_identity={'certificate_source_path': ..., 'private_key': ...}` per current docs
  2. For subject tokens: `workload_identity={'provider': ...}`
  3. Validate keys before constructing; log the dict's keys (not secrets) on failure

Example fix

# before
client = OpenAI(workload_identity={'cert': '/tmp/c.pem'})

# after
client = OpenAI(workload_identity={'certificate_source_path': '/tmp/c.pem', 'private_key': key})
Defensive patterns

Strategy: validation

Validate before calling

def is_valid_workload_identity(w: object) -> bool:
    if not isinstance(w, dict):
        return False
    return 'provider' in w or ('certificate_source_path' in w or 'private_key' in w)

assert is_valid_workload_identity(identity), 'workload_identity must be an X.509 or subject-token dict'

Type guard

def is_workload_identity_dict(w: object) -> bool:
    return isinstance(w, dict) and (('provider' in w) ^ bool({'certificate_source_path', 'private_key'} & set(w)))

Try / catch

try:
    client = OpenAI(workload_identity=identity)
except OpenAIError as e:
    if 'Invalid `workload_identity`' in str(e):
        raise ValueError('Check workload_identity keys against current docs') from e
    raise

Prevention

When it happens

Trigger: `workload_identity={'foo': 'bar'}`; passing a cert path without the expected key names; passing a string or an object instead of a supported dict shape; typos in key names like `certificate_source` vs `certificate_source_path`.

Common situations: First-time X.509 setup from docs examples; config files where nested keys got flattened or renamed; version upgrades that changed accepted shapes.

Related errors


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