An intermittent bug is the worst kind to diagnose, because it fails the most basic debugging step: reproducing it on demand. A “remove item” button in a store’s cart drawer was failing with a 403 Forbidden error for some visitors, some of the time — with nothing useful in the PHP error log to point at a cause.
Reading the failure signature
The AJAX request’s response body was a bare -1, paired with an HTTP 403 status. That specific combination is WordPress’s own signature for a failed check_ajax_referer() call — the security-nonce verification every properly-built AJAX handler performs before doing anything else. The nonce being sent by the page simply didn’t match what the server expected.
Why a genuinely valid nonce could fail
WordPress nonces aren’t permanent — they’re generated per page load and expire after roughly 24 to 48 hours, tied to a rolling time-window rather than a fixed value. The site’s LiteSpeed full-page cache, however, was configured with a 7-day TTL — meaning a cached page could be served, unchanged, to every visitor for up to a full week after it was first generated.
Any page still being served from cache more than roughly two days after it was cached was handing out a nonce that had already expired by the time a real visitor tried to use it — not because of anything wrong with that specific visitor’s session, but because the HTML itself was stale relative to WordPress’s own security clock.
The fix, and why it’s a real fix and not a workaround
Lowering the page cache TTL to 6 hours — comfortably under WordPress’s minimum nonce lifetime — resolved it immediately and completely, because it addresses the actual mismatch rather than papering over a symptom. We also removed a separate, unrelated duplicate cart interface from the checkout page while investigating, since checkout’s own order review already showed the same information.
Key takeaways
- A response body of
-1with HTTP 403 is close to a fingerprint for a failed WordPress nonce check — worth recognizing on sight. - Full-page cache TTLs and WordPress’s own security-token lifetime are two settings that have to agree with each other, and nothing enforces that by default.
- An intermittent, seemingly random bug is often a timing mismatch between two systems that each work correctly in isolation.
Running into a similar limitation in your own WooCommerce or WordPress admin? Let’s Talk — Artintech Solution builds exactly this kind of custom store tooling.