litespeedtech / litespeedtech/lscache_wp
Bug Report: Intermittent WooCommerce "My Account" login failures with LSCache/ESI
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 257
- Forks
- 123
- PR merge metrics
- No merged PRs in 30d
Description
[woocommerce_my_account] intermittent login failures >> cookies not set on POST (ESI TTL=0 workaround)
On a multisite WP install using LiteSpeed + LSCache + WooCommerce, account/login POSTs intermittently return 200 with no Set-Cookie headers.
Page is (should be) fully excluded from cache, done in the page settings and the LSCache settings.
Clearing the LSCache temporarily fixes the issue.
Converting the login block (shortcode) to a dynamic ESI fragment (TTL=0) fixes the issue. ([esi woocommerce_my_account ttl=0])
Environment
- Platform: WordPress WooCommerce Multisite on a Litespeed Server
- Page builder: Beaver Builder (account/login is in a BB HTML module containing
[woocommerce_my_account]) - Webserver / cache: LiteSpeed (LSCache, ESI enabled)
- CDN / proxy: Cloudflare (Dev Mode used during testing)
- Security plugin: Wordfence (tests done with IP whitelisted)
- PHP / WordPress / Plugin versions: WP 6.8.2, LS 7.5.0.1, Woo 10.1.2,
Summary
On the WooCommerce My Account page (also used for login), login attempts intermittently fail: the login POST sometimes returns a 200 with the login form again and no Set-Cookie headers (so no session is created). In successful attempts the POST returns 302 and the expected Set-Cookie headers (wordpress_logged_in_*, wordpress_sec_*, and _lscache_vary).
This happens despite the page being explicitly excluded from full-page caching in LSCache settings and despite Cloudflare Dev Mode and Wordfence whitelist testing. Clearing LSCache temporarily fixes the issue. Converting the login block to an ESI block with TTL = 0 (fully dynamic fragment) resolves the problem permanently in the test environment.
Steps to reproduce
- Configure a multisite WP with Wordfence, WooCommerce and LS.
- Build the My Account page using the shortcode
[woocommerce_my_account]. - Ensure the account page is excluded from LSCache (page-level + global excludes). Leave LSCache and ESI globally enabled.
- Attempt multiple logins (real browser interactions). Observe intermittent failures where the POST returns the login form again with no cookies. In some occasions it will go through for a period of time and eventually fails again. I usually had to wait a few minutes are a login was successful.
- Clearing the LSCache temporarily makes subsequent attempts succeed for a while.
- Convert the login block into an ESI block with TTL=0 and test logins, problem seems to disappear.
Response headers
Failed response (sanitized)
Status: 200
Cache-Control: no-cache, must-revalidate, max-age=0, no-store, private
X-LiteSpeed-Cache-Control: no-cache,esi=on
CF-Cache-Status: DYNAMIC
(There are NO Set-Cookie headers)
Successful response (sanitized)
Status: 302
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
X-LiteSpeed-Cache-Control: no-cache,esi=on
CF-Cache-Status: DYNAMIC
Location: /account/
Set-Cookie: _lscache_vary=REDACTED; HttpOnly; Secure; Path=/; Max-Age=172800
Set-Cookie: wordpress_sec_XXXX; HttpOnly; Secure; Path=/
Set-Cookie: wordpress_logged_in_XXXX; HttpOnly; Secure; Path=/
Key symptom: in failed POSTs the server returns the full login HTML but does not include any Set-Cookie headers, so the browser remains logged out.
Things that were tested & ruled out
- Cloudflare caching/WAF: Dev Mode enabled during tests. Behaviour persisted. (Cloudflare logs were checked; no firewall triggers correlated.)
- Wordfence blocking: the testing IP was whitelisted; Wordfence AJAX validation requests (
{login:1}) succeed consistently. Wordfence live traffic shows only successful login POSTs. (Not the failed ones.) - ModSecurity: disabled > issue persisted.
- LSCache tags:
x-litespeed-tagpresence removed/checked > not sufficient to fix. - Full-page exclude: page explicitly excluded from LSCache (global + page rules).
- Clearing LSCache: temporary fix > after clearing, logins succeed for some time until problem reappears.
Additional diagnostic notes
x-litespeed-cache-controlheader on both responses includesesi=on(ESI globally enabled).- The
privatedirective appears in the failed response's Cache-Control header. Which is a user-specific response, however, the practical effect here is that the login POST failed to includeSet-Cookie. - The initial
AJAX -> {login:1}(Wordfence) validation used earlier in the flow sometimes is skipped after converting to an ESI block; once converted to a dynamic ESI fragment (TTL=0) the final POSTs reliably set cookies. Sec-Fetch-Userheader was observed to be inconsistently present between requests (likely due to JS submission timing). This may be correlated with JS-driven form submissions, but it was not the root cause since other security layers were ruled out.
Workaround
Converting the WooCommerce login fragment into an ESI block with ttl=0 (so it is always rendered dynamically per request and never cached) removed the intermittent failures in our environment. Clearing LSCache also temporarily fixed the problem, which seems to indicate the issue is tied to how LSCache/ESI and dynamic fragments interact with the WooCommerce login POST in this particular stack.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the login flow from the listed multisite WordPress, WooCommerce, LiteSpeed/LSCache, ESI, Cloudflare, and Wordfence setup, then compare the failed and successful response headers. Done means identifying why some login POSTs omit Set-Cookie and preventing the intermittent failures without relying on the ESI TTL=0 workaround.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- backend, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 28/100