Your checkout was working fine yesterday. Today, customers click "Place Order" and nothing happens β or worse, they get a cryptic "nonce verification failed" error. Here's exactly how to diagnose and fix it.
What Is a WordPress Nonce (And Why Should You Care)?
A nonce β short for "number used once" β is a security token WordPress generates to verify that a form submission is intentional and recent. Every checkout form, login page, and admin action in WordPress carries a nonce.
When a nonce fails verification, WordPress rejects the request. For your customers, that means:
The checkout form silently refuses to submit
A "The link you followed has expired" message appears
Payment processing fails with no clear error
"Nonce verification failed" shows up in your server logs
The result? Lost sales, confused customers, and support tickets with no obvious cause.
Here's the important part most guides skip: nonces expire after 24 hours by default (technically, they're valid for two "ticks" of 12 hours each). That's usually fine. But when page caching enters the picture, everything breaks.
The #1 Cause: Page Caching Serves Expired Nonces
This is the scenario that catches 80% of store owners off guard. Here's what happens step by step:
1
Hour 0
WordPress generates a fresh nonce and embeds it in your checkout page HTML.
2
Hour 1β12
Your caching plugin (WP Rocket, LiteSpeed Cache, W3 Total Cache, Cloudflare) saves this entire page β nonce included β as a static file.
3
Hour 13β24
The nonce in the cached page crosses the first tick boundary. It's still valid, but aging.
4
Hour 25+
The nonce expires. But your caching plugin is still happily serving that same cached HTML to every visitor.
The checkout page looks perfectly fine. There's no error on the screen in many cases. The order just... doesn't go through. That's why we call this a silent failure β and it's exactly the kind of issue that can cost you days of revenue before anyone notices.
Nonce lifecycle animation
Animated diagram: a fresh nonce token ages while a page cache keeps serving the stale copy.
How to Confirm This Is Your Problem
Open your checkout page in an incognito window. View the page source (Ctrl+U / Cmd+U) and search for nonce. You'll find something like:
Now wait 5 minutes and reload the page in a fresh incognito window. Search for the nonce value again. If the value is identical, your checkout page is being cached with a stale nonce. On a properly configured site, the nonce value should change with each fresh page load.
Diagnostic Flowchart: Find Your Nonce Problem in 5 Minutes
Not sure where to start? Follow this decision tree:
Step 1 β Is the nonce value changing on each page load?
Open the checkout page in incognito. Reload 3 times. Check the nonce value each time.
Fix #1: Cache Exclusions (Solves 80% of Cases)
Tell your caching plugin to never cache WooCommerce's dynamic pages. Most caching plugins claim to do this automatically when they detect WooCommerce, but the auto-detection fails more often than you'd expect β especially after migrations, plugin updates, or when using a CDN layer on top.
Go to Settings β WP Rocket β Advanced Rules β Never Cache URLs and add:
/checkout/(.*)
/cart/(.*)
/my-account/(.*)
Also go to WP Rocket β Advanced Rules β Never Cache Cookies and confirm these are listed:
After saving, hit Clear Cache and then Preload Cache.
After Any Cache Change: Verify
1Clear all caches (plugin + CDN + server-level if applicable).
2Open the checkout page in incognito.
3Check the nonce value.
4Reload. Check the nonce value again.
5The values must be different. If they're the same, a caching layer is still serving the page from cache.
Fix #2: Plugin Conflicts
Some plugins inject their own nonces or interfere with WooCommerce's nonce verification. The most common offenders:
Security plugins (Wordfence, Sucuri, iThemes Security) β may add extra nonce checks or block requests that look automated.
Performance plugins that minify or defer JavaScript β if WooCommerce's wc-checkout.js is deferred or minified incorrectly, the nonce field may not be populated when the form submits.
Custom checkout plugins (CheckoutWC, Fluid Checkout, FunnelKit) β these replace the default checkout template and sometimes handle nonces differently.
Multi-currency or geolocation plugins β may trigger page variations that interact unpredictably with caching.
How to Isolate the Conflict
1Create a staging site (or use your hosting's staging feature). Never debug on production.
2Deactivate all plugins except WooCommerce.
3Switch to the Storefront theme.
4Test the checkout. If the nonce error is gone, the problem is a plugin or theme.
5Reactivate plugins one at a time, testing the checkout after each.
6When the error returns, you've found the culprit.
Fix #3: Extend the Nonce Lifetime (Temporary Diagnostic)
This is not a permanent fix, but it's useful for confirming that nonce expiration is the root cause. Add this to your theme's functions.php or a custom plugin:
add_filter( 'nonce_life', function() {
return 48 * HOUR_IN_SECONDS; // Extend to 48 hours (default is 24)
});
If extending the nonce lifetime makes the error disappear, you've confirmed that nonces are expiring before customers use them β which circles back to caching (Fix #1) as the underlying cause. Remove this code once you've implemented proper cache exclusions. Extending nonce lifetime weakens the security protection nonces provide.
Fix #4: Server Time Sync
WordPress nonces are time-based. If your server's clock drifts more than a few minutes from real time, nonces will expire unpredictably.
This happens most often on:
Budget shared hosting with poorly maintained servers
VPS instances where NTP (Network Time Protocol) isn't configured
Docker containers without host time sync
Check your server time via SSH or hosting terminal:
date -u
Compare the output with UTC at time.is/UTC. If there's a discrepancy of more than 30 seconds, ask your hosting provider to enable NTP sync. On a VPS you manage yourself:
sudo timedatectl set-ntp on
sudo systemctl restart systemd-timesyncd
Fix #5: Session Issues on Load-Balanced Hosting
If your hosting runs multiple application servers behind a load balancer (common on platforms like Cloudways, Kinsta, WP Engine at higher tiers, and any custom AWS/GCP setup), a customer's checkout request might hit a different server than the one that generated their nonce.
Sticky sessions
Option A: Enable sticky sessions β Configure your load balancer to route a user's requests to the same backend server for the duration of their session. On AWS ALB, this is called "session stickiness" or "target group stickiness."
Shared session store
Option B: Use a shared session store β Store WordPress sessions in Redis or Memcached instead of the default file-based storage.
The Deeper Problem: Silent Failures
Here's what makes nonce failures especially dangerous: they're silent. Your uptime monitor says the site is up. Your checkout page loads perfectly. The "Place Order" button looks normal. But orders aren't coming through.
You might not notice for hours β or days. By the time a customer emails you, you've already lost dozens of sales to a stale nonce that a cache plugin served without knowing better.
This is the exact scenario automated checkout monitoring is built for. Instead of waiting for customer complaints, a monitoring tool places a test order at regular intervals and alerts you the moment the checkout flow breaks β whether the cause is a bad nonce, an expired SSL certificate, a gateway misconfiguration, or any other silent failure.
ShopMonitor runs automated checkout tests on your WooCommerce store every hour, using real browser sessions that go through every step a customer would. If a nonce error (or anything else) stops the checkout from completing, you get an alert within minutes β not days. See also our WooCommerce checkout troubleshooting guide for the full diagnosis tree.
Catch silent checkout failures before customers do
ShopMonitor runs real test purchases through your WooCommerce checkout around the clock and alerts you the moment anything breaks β stale nonces, cache misconfigurations, gateway errors, and more.
No credit card required. Set up in 5 minutes, no code changes.
Prevention: How to Stop Nonce Errors Before They Happen
Audit your cache configuration after every plugin update. Caching plugins occasionally reset their exclusion rules during updates. Make it a checklist item.
Test your checkout after every deployment. Whether you're updating WooCommerce, switching themes, or adding a new payment gateway β run a test order. If you don't have time to do it manually every time, automate it.
Monitor the woocommerce-process-checkout-nonce field. You can add a simple health check that verifies the nonce changes on each page load. If it doesn't, your caching broke again.
Don't rely on "site up" monitoring. Pingdom and UptimeRobot check whether your server responds with a 200 status code. They don't check whether your checkout actually works. Nonce failures return 200 β the page loads fine, the checkout just silently fails.
Frequently asked questions
It means WordPress received a form submission with a security token (nonce) that is either expired, invalid, or missing. WordPress rejects the submission to prevent cross-site request forgery (CSRF) attacks. In WooCommerce, this typically manifests as a checkout that silently fails or displays an error when customers try to place an order.
Yes β this is the most common cause. Page caching plugins store a static copy of your checkout page, including the nonce token embedded in the HTML. When the cached nonce expires (after 12β24 hours), every customer who loads the cached page receives an invalid nonce. The fix is to exclude your checkout, cart, and account pages from page caching.
By default, a WordPress nonce is valid for 24 hours, spanning two 12-hour "ticks." A nonce generated at the start of a tick is valid for that tick and the next one. This means the actual validity period ranges from 12 to 24 hours depending on when within the tick the nonce was created.
Extending the nonce lifetime (e.g., to 48 or 72 hours) reduces security because it gives attackers a longer window to reuse captured nonces. It should only be used as a temporary diagnostic measure. The proper fix is to ensure your checkout page is excluded from caching so a fresh nonce is generated on every page load.
Silent checkout failures are difficult to detect because the page loads normally and returns a 200 status code. Signs include: a sudden drop in orders with no change in traffic, customer complaints about orders not going through, and nonce_verification_failed entries in your server error logs. Automated checkout monitoring tools like ShopMonitor detect these failures by running real test purchases at regular intervals.
The Checkout Block (introduced in WooCommerce 8.3+) uses a different architecture than the classic shortcode checkout and handles nonces through the Store API rather than traditional form submission. This can reduce some nonce issues, but caching can still interfere with the Store API's nonce mechanism. The same cache exclusion rules apply.
Last updated: July 2026. This guide covers WooCommerce 8.x+ with WordPress 6.5+. All caching plugin instructions verified against current versions.
About the author
Written by the Winning Solutions team β the agency behind ShopMonitor. ShopMonitor is built by founders who have been building and maintaining WooCommerce stores for over a decade. Every fix in this guide comes from real client emergencies β and ShopMonitor is the tool we built so the emergency call comes from a robot, not a customer.
How to Fix "Invalid Nonce" / Nonce Verification Failed in WordPress (2026 Guide) | ShopMonitor