Short answer
Use keys from the same account and mode on both sides: the secret key that created the session and the key that retrieves it, plus the publishable key in Stripe.js. For Connect direct charges, pass the connected account ID when you retrieve the session; for sessions created on the platform, do not. On the success page, check the session_id you read is a real cs_ ID and not the {CHECKOUT_SESSION_ID} placeholder.
Why Stripe cannot find the session, and the fix
01
Test and live keys, or two accounts, are mixed
“The ID provided isn’t valid. Either the resource doesn’t exist, or an ID for a different resource has been provided.” Stripe, Error codes (resource_missing)
A cs_test_ session cannot be read with a live key, and a session from one account cannot be read with another account’s key. This often happens when the server and the frontend load keys from different environment files. Each Stripe sandbox has its own keys too. Check that both keys are for the same mode and come from the same account or sandbox.
02
The session belongs to a connected account
“Include the connected account ID in the `Stripe-Account` header on each request” Stripe, Make API calls for connected accounts (server-side)
With Connect, a session created with the connected account ID can only be read with that same ID. Pass stripeAccount on the server call, and in Stripe.js with loadStripe(key, { stripeAccount }) if the frontend uses the session. The reverse fails too: a session created on the platform account must be read without it.
const session = await stripe.checkout.sessions.retrieve( sessionId, { stripeAccount: connectedAccountId }, );03
The success page reads the wrong ID
“This is a literal string and you must add it exactly as you see it here.” Stripe, Customize the success page
If success_url did not include the placeholder, or something rewrote it, the success page reads undefined or the literal text {CHECKOUT_SESSION_ID}. Log the value before you call retrieve.
04
Related: an old session link is reused
“It can be anywhere from 30 minutes to 24 hours after Checkout Session creation.” Stripe, Create a Checkout Session (expires_at)
This shows an expired page rather than No such checkout.session, but it is the next thing to check. Checkout Sessions expire, by default 24 hours after creation, so a saved session URL stops working. Create a new session each time the customer starts checkout.
Checked against the vendor’s docs on : Stripe docs: Error codes; Stripe docs: Connect authentication; Stripe docs: Customize the success page; Stripe API: Create a Checkout Session.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- $950Stripe Billing Fix and SetupSubscriptions, webhooks, customer portal and failed payments set up or fixed, tested in Stripe test mode.See scope and start
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
Related: Stripe “Not a valid URL” · Stripe “No such customer” (test mode) · Stripe works in test mode, not live · Stripe “No such PaymentMethod”