The error, verbatim
Jump to the fix ↓OpenAIError: The OPENAI_API_KEY environment variable is missing or empty; either provide it,
or instantiate the OpenAI client with an apiKey option, like new OpenAI({ apiKey: 'My API Key' }).
# the same error in newer versions of the SDK:
OpenAIError: Missing credentials. Please pass an `apiKey`, `workloadIdentity`, `adminAPIKey`,
or set the `OPENAI_API_KEY` or `OPENAI_ADMIN_KEY` environment variable.
# Python, openai 3.x:
openai.OpenAIError: Missing credentials. Please pass an `api_key`, `workload_identity`, `admin_api_key`,
or set the `OPENAI_API_KEY` or `OPENAI_ADMIN_KEY` environment variable.
# OpenAI's Codex CLI, with a provider that reads the key from the environment:
ERROR: Missing environment variable: `OPENAI_API_KEY`.
Tested on
- openai (JS)
- 4.104.0 and 7.23.0
- openai (Python)
- 1.109.1 and 3.19.2
- dotenv / python-dotenv
- 18.0.3 / 1.2.3
- Codex CLI
- 0.158.0
- Runtime
- Node 24.14.0, Python 3.14.5
- OS
- Windows 11 Pro
Contents
The key is in your .env file, and the SDK still says it’s missing. Almost always, that’s because nothing ever read the file. A .env file is just a text file: the SDK reads process.env (or os.environ), and something has to copy the file into it first.
Which wording you have
OpenAI has reworded this error, so what you see depends on the SDK version, and the Codex CLI has its own. They all mean the same thing:
| SDK | Message starts with |
|---|---|
| JavaScript 4.x | The OPENAI_API_KEY environment variable is missing or empty |
| JavaScript 7.x | Missing credentials. Please pass an apiKey… |
| Python 1.x | The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_API_KEY environment variable |
| Python 3.x | Missing credentials. Please pass an api_key, workload_identity, admin_api_key… |
| Codex CLI | Missing environment variable: OPENAI_API_KEY (it has its own section below) |
The fix
Load the .env file before creating the client.
JavaScript, as the very first line of your entry file:
import 'dotenv/config';
import OpenAI from 'openai';
const client = new OpenAI();Or skip the package entirely and let Node read the file (Node 20.6+):
node --env-file=.env app.mjsPython, before the client is created:
from dotenv import load_dotenv
load_dotenv()
from openai import OpenAI
client = OpenAI()When it still fails: you ran it from another folder
This is the version that survives the fix above. dotenv looks for .env in the folder you ran the command from, not the folder your script lives in. Run node src/app.mjs from one level up, or start it from an editor that uses a different working folder, and it finds nothing.
It doesn’t fail loudly, either. Newer dotenv prints one line, and the number is the clue:
◇ injected env (0) from .env
(0) means it found no .env where it looked. When the file is found you’ll see (1) or more.
Point dotenv at the file next to the script instead of the current folder:
import dotenv from 'dotenv';
import { fileURLToPath } from 'node:url';
dotenv.config({ path: fileURLToPath(new URL('.env', import.meta.url)) });In the Codex CLI: “Missing environment variable”
The Codex CLI prints a shorter version, and the cause is different:
ERROR: Missing environment variable: `OPENAI_API_KEY`.
It appears when Codex’s config.toml uses a model provider that takes its key from an environment variable, the kind of setup that config tools and Azure or gateway presets write:
model_provider = "openai-key"
[model_providers.openai-key]
name = "OpenAI with an API key"
base_url = "https://api.openai.com/v1"
env_key = "OPENAI_API_KEY"
wire_api = "responses"
The name in the message is whatever env_key says. With env_key = "AI_GATEWAY_API_KEY", the same run printed Missing environment variable: `AI_GATEWAY_API_KEY`. So read the name in your error, and set exactly that variable.
Set the variable in the terminal you start Codex from. In PowerShell:
$env:OPENAI_API_KEY = "sk-..."
codexIn bash or zsh:
export OPENAI_API_KEY="sk-..."
codexOr put it in a .env file in Codex’s own folder, the one CODEX_HOME points to (.codex in your user folder unless you’ve moved it), not in your project:
OPENAI_API_KEY=sk-...Without a custom provider, a missing key looks different: the default setup kept retrying with 401 Unauthorized and “Missing bearer or basic authentication in header”. That’s Codex with no sign-in and no key at all.
The next error you might see
Once the key loads, the request can still be rejected with 401 Incorrect API key provided. If that happens with a key you know is right, an old key set somewhere else is overriding your .env, and neither dotenv nor --env-file replaces it. That has its own write-up: OpenAI 401 Incorrect API key provided.
How this was tested
A project with a .env holding a test key, run with the OpenAI SDK in JavaScript (4.104.0 and 7.23.0) and Python (1.109.1 and 3.19.2) on Windows 11. Each cause was produced on purpose: no loader at all, and loaders run from a different folder. Every message above is the SDK’s real output. No real API key was used; the test key was invented, and this error happens before any request is sent. The Codex CLI 0.158.0 runs used a separate, empty CODEX_HOME folder with the provider config shown above.
— N.K., end of entry No.021