WooCommerce fixes / session has expired

WooCommerce "Session Has Expired"? Causes & Fix

Customers reach checkout, hit Place order, and get thrown back with "Sorry, your session has expired. Return to shop" — cart empty, sale gone. It's almost never the customer's fault. Here's what's actually breaking.

Last updated: 16 Jul 2026 · ~7 min read

Quick answer

The usual cause is a full-page or edge cache — Varnish, nginx fastcgi_cache, Cloudflare, a host's page cache — serving one cached copy of the cart or checkout page to everyone, so the security nonce in the form doesn't match the visitor's session. A WAF stripping the wp_woocommerce_session_ cookie does the same thing. Exclude cart, checkout and my-account from every cache layer.

What "your session has expired" actually means

WooCommerce gives every shopper a session, tracked by a wp_woocommerce_session_ cookie, and stamps each checkout form with a security nonce tied to it. When the form is submitted, WooCommerce checks the nonce against the session. If they don't match, it refuses the submission and shows this notice. It isn't a timer running out — it's a mismatch.

From the owner's side you often see nothing: no order, no failed order, no gateway attempt, just traffic that reaches checkout and disappears. That's what makes this one expensive. If your checkout conversion dropped off a cliff after a caching, CDN or security change, this notice is the first thing to look for.

The most common causes (most likely first)

  1. A full-page or edge cache is serving cart and checkout to everyoneThe response headers on /checkout/ show a cache HITx-cache, cf-cache-status, x-litespeed-cache, or a Varnish age header. Everyone gets one visitor's cached page, complete with their nonce. WooCommerce sets DONOTCACHEPAGE on these pages, which caching plugins respect — but Varnish, nginx fastcgi_cache and Cloudflare never see a PHP constant, so they cache it anyway. Started after a CDN or host caching change? This is it.
  2. A WAF, proxy or CDN is stripping the session cookieIn DevTools → Application → Cookies on the checkout page, there's no wp_woocommerce_session_ cookie at all, or it changes on every reload. Some security layers and cookie-consent scripts drop cookies they don't recognise, so WooCommerce hands out a fresh session per request and no nonce ever matches.
  3. The store answers on two hostnames, so the cookie doesn't come backFails on www but not the bare domain (or vice versa), or on http before a redirect to https. The session cookie is set on one host and the form is posted to the other, so it isn't sent. Check that Site Address and WordPress Address in Settings → General match the URL customers actually browse, and that redirects happen before checkout, not during it.
  4. The shopper's login expired between loading checkout and submitting itOnly affects logged-in customers, usually ones who left checkout open a long time or logged out in another tab. Nonces are tied to the user, so when the login session ends the nonce on the open page is no longer valid for whoever is now submitting it. Rare, and genuinely a timeout — reloading checkout fixes it.
  5. A persistent object cache is evicting session dataIntermittent and unpredictable, on a store running Redis or Memcached. WooCommerce sessions get read from the object cache; if it's undersized and evicting keys, or gets flushed, sessions vanish mid-checkout. Look for eviction counts on the cache server and for anything that flushes the cache on a schedule.

Where to look first

Losing sales to a bounce you never see?

This is the worst kind of break: there's no failed order to look at, just customers vanishing at the last step. DiagnosticIQ's free dashboard watches the buying funnel so a checkout that stops completing shows up as a flagged signal instead of a quiet dip in revenue, and Checkout Guard adds checkout-lane depth to the pinpoint diagnosis. That said, the cache-exclusion fix above is the whole answer for most stores — go and check your headers first.

Get the free plugin

Made by Prima Digital — the team behind this guide. Free forever; no card to install.

How to know you fixed it

Verify

curl -I on the checkout URL shows a cache MISS or BYPASS (or no cache header at all), and a full guest order placed in a private window reaches the order-received page without the notice.

Frequently asked

Was the customer charged?

No. WooCommerce rejects the submission before it creates the order or contacts the gateway. There's no charge and no order — which is exactly why these losses are invisible.

Is the customer's cart really gone?

Usually, from their point of view — the notice sends them back to the shop with nothing. If the session cookie was stripped or the page was cached, WooCommerce has no way to link them back to the cart they built.

Should I just turn off caching?

No — turn it off for the pages that need a session. Cart, checkout and my-account should never be cached; everything else can be. If you must test, disable the cache briefly to confirm the diagnosis, then re-enable with proper exclusions.

Why can't I reproduce it?

Because you're logged in as admin, and almost every cache and optimiser skips logged-in users. Always test in a private window, as a guest, on the same connection type your customers use.

>_
John O'Keane — Founder, Prima Digital · LinkedIn
Contributions by David Zhang · LinkedIn
I build DiagnosticIQ, the WooCommerce diagnostic plugin, and I've watched "your session has expired" quietly eat a store's checkout conversion for weeks because a CDN was caching the checkout page.