Stripe Invalid API Key: test/live mix-up
Stripe returns Invalid API Key provided when the key your server sends isn't a valid key for any Stripe account: it was mistyped, cut off, wrapped in quotes or spaces, or it was rolled or deleted in the Dashboard. After go-live it usually means the live keys were pasted into the wrong place, or the hosting env vars still hold an old value.
Cause: The secret key (sk_live_... or sk_test_...) the server sends doesn't match a current key on your Stripe account, or the keys were swapped between slots or modes.
How to fix it
- Open the API keys page in the Stripe Dashboard and check you are looking at live mode, not a sandbox or test mode.
- Copy the live secret (
sk_live_) or restricted (rk_live_) key again and paste it into your host's production env var with no quotes, spaces or line breaks. - Put the publishable key (
pk_live_) only in front-end code, and the secret key only on the server. Swapping them gives "This API call cannot be made with a publishable API key". - Keep each pair in the same mode:
pk_live_withsk_live_,pk_test_withsk_test_. Live prices and the live webhook signing secret (whsec_) belong with the live keys. - Redeploy after changing env vars. Front-end variables are built into the bundle, so the old value stays live until you rebuild.
- If the key was rolled or deleted, update every place that used it (server, edge functions, background jobs).
Example
Illustrative example, not from a customer project.
# Production env vars
- STRIPE_SECRET_KEY="sk_test_..." # test key, quoted
- NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...
+ STRIPE_SECRET_KEY=sk_live_... # live key, same mode as the publishable key
+ NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...
FAQ
I get "This API call cannot be made with a publishable API key". Is that the same problem?
It's the same mix-up the other way round. A pk_ key is in the slot where the server needs an sk_ or rk_ key. Swap the two values.
Everything is on live keys, but Stripe says "No such price" or "a similar object exists in test mode".
Your keys are fine, but the price or customer ID was created in test mode. See resource_missing.
Payments work on live keys, but webhooks fail with a signature error.
Live webhook endpoints have their own signing secret. See webhook signature verification failed.
Is it safe to paste my secret key somewhere to check it?
No. Treat sk_ and rk_ keys like passwords. If one was exposed, roll it in the Dashboard and update your env vars.
Get a $149 diagnosis See pricing Stripe still not live? We take it live at a fixed price.
- Fixed, or we keep working free until it is (within the written scope).
- A human reviews every fix before it ships.
- Read-only access; fixes arrive as pull requests you merge.
- Your $149 diagnosis is credited in full toward any paid job.
Built with Lovable, Bolt, Replit, Cursor or v0? See rescue by platform and the security checklist.