Skip to main content

artintechsolution.com

Fixing an Intermittent 403 Error Caused by Cache TTL

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 -1 with 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.

Leave a Reply

Your email address will not be published. Required fields are marked *