Quick answer: This WooCommerce error appears when the session/cookie check or a security nonce fails, most often because a cache/CDN is serving an old page or blocking WooCommerce’s dynamic requests. Fix it by bypassing cache on cart/checkout/account pages and WooCommerce cookies/endpoints, confirming your site URLs (www/HTTPS) match, and ensuring browser cookies are set.
Use the checklist and copy-paste rules below for common hosts, Cloudflare, WP Rocket, LiteSpeed, W3TC, and Nginx/Apache.
WooCommerce keeps showing “Sorry, your session has expired. Return to shop.” when I add to cart or hit checkout. How do I fix this? I’m using a cache/CDN.
WooCommerce relies on several first-party cookies (e.g., wp_woocommerce_session_*, woocommerce_cart_hash, woocommerce_items_in_cart) and dynamic endpoints (for example, ?wc-ajax=*) to keep carts and nonces in sync. If a page is cached when those values change or if cookies are ignored, WooCommerce treats the request as stale and throws “session expired.”
/cart/, /checkout/, /my-account/, /add-to-cart/*, order-pay/received pages.add-to-cart, wc-ajax=* (e.g., get_refreshed_fragments, add_to_cart).woocommerce_items_in_cart, woocommerce_cart_hash, or wp_woocommerce_session_* are present, bypass/disable cache for that request.wp_woocommerce_session_* on your domain.COOKIE_DOMAIN in wp-config.php: remove it if you find it. Let WordPress handle cookie scope automatically.Use these examples as a starting point and adapt paths to your setup.
set $skip_cache 0;
# Bypass cache if WooCommerce cookies are present
if ($http_cookie ~* "wp_woocommerce_session_|woocommerce_cart_hash|woocommerce_items_in_cart") {
set $skip_cache 1;
}
# Bypass cache on key endpoints/pages
if ($request_uri ~* "(?:/cart/|/checkout/|/my-account/|/addons/|/wc-api/|/order-pay/|/order-received/)") {
set $skip_cache 1;
}
if ($arg_wc-ajax) { set $skip_cache 1; }
if ($arg_add-to-cart) { set $skip_cache 1; }
# Example fastcgi/proxy cache conditions
location / {
# your usual config...
if ($skip_cache = 1) {
add_header X-Bypass-Reason "WooCommerce dynamic request";
# don't use cache here (fastcgi_no_cache/proxy_no_cache/etc.)
}
}
<IfModule mod_headers.c>
<FilesMatch "(cart|checkout|my-account|order-pay|order-received)">
Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0"
</FilesMatch>
</IfModule>
*example.com/cart/*, *example.com/checkout/*, *example.com/my-account/*, plus Query String contains wc-ajax= or add-to-cart.wp_woocommerce_session_ or woocommerce_items_in_cart./cart/, /checkout/, /my-account/./cart/, /checkout/, /my-account/.Cookie: header containing wp_woocommerce_session_*. If missing, a CDN/proxy is stripping cookies. Adjust its settings.www and non-www, or HTTP and HTTPS, the browser will not send the session cookie. Fix the canonical domain and set redirects accordingly.Can I extend the lifetime of WooCommerce nonces?
You can filter nonce lifetimes in WordPress, but it’s better to resolve cache/cookie issues so fresh, uncached pages are served to shoppers.
What exactly should never be cached?
Cart, checkout, account pages; WooCommerce AJAX endpoints (any request containing wc-ajax=); and any request that includes WooCommerce session/cart cookies.
“Session expired” almost always traces back to cache or cookie handling. Bypass cache for WooCommerce’s dynamic pages, respect WooCommerce cookies, keep URLs consistent, and verify cookies are present on live requests. Once those are in place, the error disappears.
WP Assistant is a free tool created by Atiba Software, a WordPress design and development company located in Nashville, TN. If you need more personalized WordPress assistance let us know, and we’ll get back to you ASAP!