Stripe API error
No such price: 'price_...'
Stripe returns "No such price: 'price_...'" (code resource_missing, an invalid_request_error) when the price ID you sent does not exist in the account and mode of the secret key that made the request. The usual cause after going live is a price ID copied from a sandbox or test mode while the server now uses an sk_live_ key: Stripe's docs say API objects in one mode are not accessible to the other, so the live account has no price with that ID. Other causes are a product ID (prod_...) where a price ID belongs, a key from a different Stripe account, or an ID that was never a real price, such as an env var that was not set. Create or copy the price in live mode, put the live price ID in the live environment variables, and redeploy. Checked against Stripe's docs and the raw error bodies quoted in Stripe's own repositories on 2026-10-27.
Webhooks fail after the same switch to live keys? See whether the webhook secret differs in test and live mode.
What the error body looks like
A Stripe CLI issue shows the raw body for a subscription created with a price ID that did not resolve: HTTP 400, type invalid_request_error, code resource_missing, and a param naming the field. In a Checkout Session the param is the line item, such as line_items[0][price]; in a subscription it is items[0][price]. In that issue the ID was a placeholder the tool never filled in, the same thing an unset environment variable does. Stripe's error codes page describes resource_missing as an ID that is not valid: the resource does not exist, or an ID for a different resource was provided.
{
"error": {
"code": "resource_missing",
"doc_url": "https://stripe.com/docs/error-codes/resource-missing",
"message": "No such price: '${.env:PRICE_ID}'",
"param": "items[0][price]",
"type": "invalid_request_error"
}
}a similar object exists in live mode, but a test mode key was used
When the ID exists in the other mode of the same account, Stripe adds a sentence to the message. A stripe-python issue quotes it as "a similar object exists in live mode, but a test mode key was used to make this request", and forum threads quote the reverse, a test mode object with a live mode key. That sentence tells you the ID is right and the key is from the other mode. Without it, the price is not in this account at all: check that the key and the price come from the same Stripe account.
Test mode, sandboxes and live mode have different price IDs
Stripe's docs say objects in a sandbox or test mode are not accessible in live mode. The Copy to live mode button on a product page copies the product with its prices into live mode, and each copy is a new live product with new IDs, so the live price ID is never the test one. A new sandbox also creates new IDs: Stripe tells you to update anything in your tests that depends on specific test object IDs.
Keep price IDs out of your code
A price ID hard-coded in a component or an Edge Function works in test and breaks on the first live checkout. Put it in an environment variable per environment, or look the price up by a lookup_key, which you set to the same value on the test and the live price. Stripe's docs describe lookup keys for exactly this: render and bill a price without hard-coding its ID.
const prices = await stripe.prices.list({ lookup_keys: ['pro_monthly'], active: true })
const price = prices.data[0]
if (!price) throw new Error('No active price with lookup key pro_monthly in this Stripe mode')The variable is set, and the error still shows the old ID
On Vercel, a new value reaches only deployments created after you save it, so redeploy. A price ID read in client code under NEXT_PUBLIC_ or VITE_ is copied into the bundle at build time, so it changes only after a new build. In a Supabase Edge Function, set the secret with supabase secrets set and check it in the dashboard for the project you call.
Checklist
How to fix it, then check the fix
- 01Read the error message and param: the quoted ID, and whether it mentions a similar object in the other mode.
- 02Check the key mode: sk_test_ or rk_test_ keys reach the sandbox or test mode, sk_live_ or rk_live_ keys reach live mode.
- 03Open the price in the Stripe Dashboard in the same mode as the key and copy its price_ ID, not the product prod_ ID.
- 04Set that ID in the environment variables of the matching environment (live IDs in Production, test IDs in Preview and Development), then redeploy.
- 05Check the price from the server with the same key the app uses:
curl https://api.stripe.com/v1/prices/price_123 -u "$STRIPE_SECRET_KEY:" - 06Start one checkout in live mode and confirm the session is created before you announce the launch.
Related
Related guides
Sources
Official docs behind this checklist
Browse all launch guides · Read resources · How to make and check your next change
FAQ
FAQ for builders before launch
Can I use a test price ID with a live key?
No. Test and live objects are separate, so a live key never finds a test price. Copy the product to live mode and use the new live price ID.
Why does it say No such price when I passed a product ID?
Checkout line items and subscription items take a price ID (price_...). A product ID (prod_...) is a different resource, so the lookup fails with resource_missing.