← Decline Codes
Soft Decline

Stripe Decline Code · Glossary

insufficient_funds

When Stripe returns insufficient_funds, the customer's bank declined the charge because their account or card doesn't have enough available balance to cover the transaction amount.

Recoverable·60–75% with smart retries·Updated May 2026

What It Means

What insufficient_funds actually means.

When Stripe returns insufficient_funds, the customer's bank declined the charge because their account or card doesn't have enough available balance to cover the transaction amount. This is a soft decline — meaning the card itself is valid, the customer is real, and the payment can succeed once funds are available.

Not sure if this code is recoverable for your specific situation? Use the Stripe Failure Lookup →

Why It Happens

The root causes.

  • 1Low checking/savings balanceCustomer's debit card or bank-linked card simply ran out of funds at the time of billing
  • 2Credit limit maxed outCredit card is at or near its limit, leaving no available credit for the charge
  • 3Billing date bad timingCharge fires before the customer's paycheck clears (common mid-month for monthly subscriptions)
  • 4Temporary hold reducing available balanceA pending authorization elsewhere (hotel, rental, etc.) has temporarily reduced available funds even if the statement balance looks fine
  • 5Currency conversion shortfallFor international customers, exchange rate fluctuation caused the converted amount to exceed available balance

What NOT to Do

Common mistakes that make it worse.

Don't retry immediately (within the same hour)

The single most common mistake is triggering an automatic retry within minutes. The funds aren't there — retrying instantly just racks up failed attempt fees at the issuing bank, increases the chance of the card being flagged, and burns your retry attempts with no upside. Some issuers will soft-block a merchant after 3+ rapid failed attempts on the same card.

Don't send a generic "payment failed" email

Blasting a cold "your payment didn't go through, update your card" email for an insufficient_funds code is wrong messaging — the card is fine. Asking them to update their card creates friction and confusion when all they need is a few days.

Retry Timing

Optimal retry schedule.

AttemptTimingRationale
Retry 13 days after failureCovers weekly paid customers who top up quickly
Retry 27 days after failureCatches bi-weekly paycheck cycles
Retry 314–15 days after failureHits the mid-month or end-of-month salary deposit window
Retry 4 (final)21–28 days after failureLast catch before dunning escalation

Best practice: If you know your customer's billing country, align Retry 3 specifically to local payday norms:

insufficient_funds follows a paycheck cycle logic, not a random window.

* 🇮🇳 India — End of month (25th–1st)

* 🇺🇸 USA — 1st and 15th (bi-weekly common)

* 🇬🇧 UK — Last working day of month

Smart signal: If a customer has historically paid successfully, weight your retry more aggressively. A long-tenure customer hitting insufficient_funds once has a 70%+ chance of self-resolving within 7 days.

Recovery Benchmark

What good looks like.

MetricResult
Overall recovery rate60–75% with smart retries
Recovery within 7 days~45–50%
Recovery within 30 days~65–72%
Recovery with dunning email+8–12% lift on top of retries
Recovery rate without any retry logic~20–25% (passive)

A well-tuned dunning system (smart retry timing + personalized email sequence) should recover 65%+ of insufficient_funds failures. If you're below 50%, your retry timing is likely off or your email copy is asking customers to update a card that doesn't need updating.

At Scale

How to handle it at scale.

Automated

  • Webhook trigger: Listen to invoice.payment_failed → check failure_code === 'insufficient_funds' → tag customer segment in your CRM as "funds-related failure"
  • Smart retry scheduler: Enqueue retries at Day 3, Day 7, Day 14 — NOT via Stripe's default Smart Retries (which don't account for payday cycles natively)
  • Email sequence trigger: Fire a soft, empathetic email — not a "update your card" CTA. Something like: "We'll try again in a few days — no action needed from you right now."
  • Pause not cancel: Keep the subscription in past_due state during retry window — do NOT immediately cancel or downgrade

Manual Escalation

  • High-value accounts (MRR > $X threshold): Route to human outreach after Retry 2 fails — a personal Slack/email from your team recovers 20–30% of high-ACV accounts that automation misses
  • Repeat offenders (2nd+ month): Flag for manual review — could indicate genuine financial distress, wrong payment method on file, or churn risk requiring account manager intervention
  • Localization triggers: International customers in high-inflation markets (BR, IN, NG) may need a local payment method switch — manual outreach to offer UPI, Boleto, or local wallets can recover payments automation can't

Before you retry

Most insufficient_funds failures are retried on the wrong schedule — which recovers the payment about 30% of the time. The other 70% leaves permanently. See what this code is actually costing at your MRR before deciding how to handle it.

See what insufficient_funds costs me →

Stop leaving revenue on the table

insufficient_funds is recoverable. Most teams don't have the retry logic to prove it.

Recurflux handles code-specific retry scheduling, adaptive dunning, and dispute intelligence across all 30 Stripe decline codes. Connect in under 5 minutes.