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
- Use a documented X.509 shape: `workload_identity={'certificate_source_path': ..., 'private_key': ...}` per current docs
- For subject tokens: `workload_identity={'provider': ...}`
- 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
- Copy identity dict shapes verbatim from current SDK docs — keys are exact
- Log identity keys (never private values) when debugging construction failures
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
- The `api_key` and `workload_identity` arguments are mutually
- X.509 workload identity cannot be changed after client const
- "Could not resolve authentication method. Expected either ap
- The token file at {token_file_path} is empty.
- Failed to read the token file at {token_file_path}: {e}
AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28).
Data as JSON: /api/errors/0e998ceb71bb0596.
Report an issue: GitHub.