The error, verbatim
Jump to the fix ↓AuthenticationError: 401 Incorrect API key provided: sk-old-s*****************1111.
You can find your API key at https://platform.openai.com/account/api-keys.
code: invalid_api_key | type: invalid_request_error
# Python:
openai.AuthenticationError: Error code: 401 - {'error': {'message': 'Incorrect API key provided: sk-old-s*****************1111. ...
Tested on
- openai (JS)
- 7.23.0
- openai (Python)
- 3.19.2
- dotenv / python-dotenv
- 18.0.3 / 1.2.3
- Runtime
- Node 24.14.0, Python 3.14.5
- OS
- Windows 11 Pro
Contents
You paste a fresh key into .env, run your code, and OpenAI still says it’s incorrect. Before you regenerate the key again, read the error closely, because it tells you exactly which key was sent.
Read the key in the error
OpenAI echoes the key it received: the first 8 characters and the last 4, with the middle masked.
Incorrect API key provided: sk-old-s*****************1111.Compare those 12 characters with the key in your .env:
- They don’t match → your code sent a different key than the one in
.env. An older key set somewhere else is winning. Go to the next section. - They match → the key itself is wrong: mistyped, revoked, or from a different organisation or project. Create a new one in the OpenAI dashboard.
Why an old key beats your .env
This surprised me more than anything else in the test. If OPENAI_API_KEY is already set in your environment (from your system settings, your shell profile, or an old setx), loading .env does not replace it:
How .env is loaded |
Shell already has an old key | Key actually sent |
|---|---|---|
import 'dotenv/config' (JS) |
yes | the old one |
node --env-file=.env |
yes | the old one |
load_dotenv() (Python) |
yes | the old one |
In every case the request went out with the old key, and the 401 showed its first and last characters, not the new key’s. That’s the whole trap: you can regenerate keys all day and paste each one into .env, and none of them is ever used.
The fix
Option 1: let .env win. Tell the loader to overwrite what’s already set.
// JavaScript
import dotenv from 'dotenv';
dotenv.config({ override: true });# Python
from dotenv import load_dotenv
load_dotenv(override=True)Option 2: remove the old key at its source, so there’s only one. Check whether one is set:
echo $env:OPENAI_API_KEY # PowerShell
echo %OPENAI_API_KEY% # Command Prompt
echo $OPENAI_API_KEY # macOS / LinuxIf it prints a key, find where it’s defined. On Windows that’s usually Start → “Edit the system environment variables” → Environment Variables; on macOS or Linux, your shell profile (~/.zshrc, ~/.bashrc). Delete it there, then open a new terminal and restart your editor, because running programs keep the environment they started with.
What didn’t work
How this was tested
The OpenAI SDK in JavaScript (7.23.0) and Python (3.19.2) on Windows 11, calling the real API with invented test keys: one in .env and a different one set in the shell. Each loader (dotenv, node --env-file, python-dotenv) was run with and without the override. No real key was used; every result above is OpenAI’s actual 401 response, and the key characters shown are from the invented test keys.
— N.K., end of entry No.023