Skip to main content
RapidDev - Software Development Agency
stripe-guide

How to fix the 'no such customer' error in Stripe

The 'No such customer' error in Stripe means you're referencing a customer ID that doesn't exist in the current mode. The most common cause is creating a customer in test mode but trying to charge them in live mode, or vice versa. Fix it by ensuring your API keys and customer IDs are from the same Stripe environment.

What you'll learn

  • Why the 'No such customer' error occurs
  • How test and live mode data are completely separate
  • How to verify a customer ID exists in the correct mode
  • How to prevent test/live mode mismatches in your code
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner5 min read10 minutesStripe API v2024-12+, Node.js 18+March 2026RapidDev Engineering Team
TL;DR

The 'No such customer' error in Stripe means you're referencing a customer ID that doesn't exist in the current mode. The most common cause is creating a customer in test mode but trying to charge them in live mode, or vice versa. Fix it by ensuring your API keys and customer IDs are from the same Stripe environment.

Why Stripe Says 'No Such Customer'

Stripe test mode and live mode maintain completely separate databases. A customer created with sk_test_ only exists in test mode. If you try to reference that customer ID (cus_...) using a live mode key (sk_live_), Stripe returns 'No such customer'. This also happens when a customer was deleted, the ID is mistyped, or you're referencing a customer from a different Stripe account.

Prerequisites

  • A Stripe account with access to the Dashboard
  • Node.js 18+ with the Stripe npm package installed
  • A stored customer ID to verify

Step-by-step guide

1

Identify which mode you're operating in

Check your API key prefix. sk_test_ means test mode; sk_live_ means live mode. All data created with one key type is invisible to the other.

typescript
1const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
2console.log('Mode:', process.env.STRIPE_SECRET_KEY.startsWith('sk_test_') ? 'TEST' : 'LIVE');

Expected result: Console outputs 'TEST' or 'LIVE' confirming your current mode.

2

Look up the customer in the Dashboard

Go to Stripe Dashboard → Customers → search for the customer ID (cus_...). Make sure the test/live mode toggle at the top matches the mode where the customer was created. If you're in test mode, you won't see live mode customers.

Expected result: You find the customer in the correct mode, or confirm it doesn't exist in the mode you're using.

3

Verify the customer exists via API

Use stripe.customers.retrieve() to check if the customer ID is valid for your current API key. This confirms whether the mismatch is mode-related or the customer was deleted.

typescript
1async function checkCustomer(customerId) {
2 try {
3 const customer = await stripe.customers.retrieve(customerId);
4 if (customer.deleted) {
5 console.log('Customer was deleted');
6 } else {
7 console.log('Customer found:', customer.email);
8 }
9 } catch (err) {
10 if (err.code === 'resource_missing') {
11 console.error('Customer does not exist in this mode');
12 } else {
13 console.error('Error:', err.message);
14 }
15 }
16}
17
18checkCustomer('cus_your_customer_id');

Expected result: The function confirms whether the customer exists, was deleted, or is missing from the current mode.

4

Fix the mode mismatch in your application

Ensure your app uses the correct API key for each environment. Store test keys in your development .env and live keys in production environment variables. Never mix them.

typescript
1# .env.development
2STRIPE_SECRET_KEY=sk_test_51ABC...
3
4# .env.production
5STRIPE_SECRET_KEY=sk_live_51ABC...

Expected result: Your development environment uses test keys and production uses live keys. No cross-mode references occur.

5

Add a safety check before using customer IDs

Add a validation step that catches mismatched customer references early, before they cause errors in payment flows.

typescript
1async function safeGetCustomer(customerId) {
2 try {
3 const customer = await stripe.customers.retrieve(customerId);
4 if (customer.deleted) {
5 throw new Error(`Customer ${customerId} has been deleted`);
6 }
7 return customer;
8 } catch (err) {
9 if (err.code === 'resource_missing') {
10 throw new Error(
11 `Customer ${customerId} not found. Check if you're using the correct test/live API key.`
12 );
13 }
14 throw err;
15 }
16}

Expected result: Your code provides clear error messages that help identify mode mismatches instead of failing with a generic Stripe error.

Complete working example

customer-check.js
1require('dotenv').config();
2const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
3
4const isTestMode = process.env.STRIPE_SECRET_KEY.startsWith('sk_test_');
5console.log(`Running in ${isTestMode ? 'TEST' : 'LIVE'} mode`);
6
7async function safeGetCustomer(customerId) {
8 if (!customerId || !customerId.startsWith('cus_')) {
9 throw new Error(`Invalid customer ID format: ${customerId}`);
10 }
11
12 try {
13 const customer = await stripe.customers.retrieve(customerId);
14 if (customer.deleted) {
15 throw new Error(`Customer ${customerId} has been deleted`);
16 }
17 return customer;
18 } catch (err) {
19 if (err.code === 'resource_missing') {
20 throw new Error(
21 `Customer ${customerId} not found in ${isTestMode ? 'test' : 'live'} mode. ` +
22 'Verify the customer exists in this environment.'
23 );
24 }
25 throw err;
26 }
27}
28
29async function createPaymentForCustomer(customerId, amount, currency) {
30 const customer = await safeGetCustomer(customerId);
31 console.log(`Creating payment for ${customer.email}`);
32
33 const paymentIntent = await stripe.paymentIntents.create({
34 amount,
35 currency: currency || 'usd',
36 customer: customerId,
37 automatic_payment_methods: { enabled: true },
38 });
39
40 return paymentIntent;
41}
42
43module.exports = { safeGetCustomer, createPaymentForCustomer };

Common mistakes when fixing the 'no such customer' error in Stripe

Why it's a problem: Creating customers in test mode and charging them with live mode keys

How to avoid: Test and live mode are completely separate databases. Customers created with sk_test_ only exist in test mode. You must recreate customers in live mode for production.

Why it's a problem: Storing the customer ID but not the mode it was created in

How to avoid: Always store which Stripe environment a customer belongs to in your database, or use separate database fields for test and live customer IDs.

Why it's a problem: Assuming deleted customers still exist

How to avoid: Check customer.deleted in the API response. Deleted customers return a minimal object with deleted: true instead of a resource_missing error.

Why it's a problem: Copying customer IDs from a different Stripe account

How to avoid: Customer IDs are unique per Stripe account. A cus_ ID from one account doesn't exist in another, even if both are in the same mode.

Best practices

  • Always use matching API keys and data — test keys with test data, live keys with live data
  • Store the Stripe environment (test/live) alongside customer IDs in your database
  • Validate customer IDs before using them in payment flows
  • Use a helper function that provides clear error messages for missing customers
  • Log the current API mode at server startup for quick debugging
  • When going live, create new customers instead of trying to migrate test data

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

Write a Node.js helper function that safely retrieves a Stripe customer by ID, handles the 'no such customer' error with a clear message about test/live mode mismatch, and checks if the customer was deleted. Include mode detection based on the API key prefix.

Stripe Prompt

Create a Stripe customer validation module in Node.js that checks whether a customer ID exists in the current mode (test or live), handles resource_missing errors, detects deleted customers, and provides actionable error messages.

Frequently asked questions

Can I move a customer from test mode to live mode?

No. Test and live mode are completely separate. You need to create new customers in live mode. There is no migration path between test and live data in Stripe.

Why does my customer ID work locally but not in production?

Your local environment likely uses sk_test_ while production uses sk_live_. Customers created in test mode don't exist in live mode. Create new customers using your live key.

How can I tell if a customer was deleted?

Call stripe.customers.retrieve(id). If the customer was deleted, the response includes a 'deleted: true' field. It does not throw a resource_missing error — only customers that never existed or belong to another mode throw that.

What does the cus_ prefix mean?

All Stripe customer IDs start with cus_ followed by a unique alphanumeric string. The prefix doesn't indicate test or live mode — you must check the API key used to create or access the customer.

I accidentally deleted a customer in Stripe. Can I recover them?

No. Stripe does not support undeleting customers. You need to create a new customer. Their payment methods, subscriptions, and invoices associated with the deleted customer are also removed.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.