Environment:
- LiteSpeed Cache: 7.8.0.1
- WooCommerce: 10.6.1
- OpenLiteSpeed (not LiteSpeed Enterprise)
- PHP 8.3
Description:
Since WooCommerce 10.1.0, WC_Cache_Helper::prevent_caching() was moved from the wp action to the wp_headers filter at priority 5 (see comments in code). This change causes LiteSpeed Cache to never cache any pages on WooCommerce stores.
Root cause:
WooCommerce's prevent_caching() now fires on wp_headers unconditionally for every page load, calling set_nocache_constants() which defines DONOTCACHEPAGE = true. LiteSpeed Cache's WooCommerce compatibility handler (thirdparty/woocommerce.cls.php) was written to handle the old wp action hook and does not override the new wp_headers hook. As a result, DONOTCACHEPAGE is always true before LiteSpeed finalises cache control, causing Control::is_cacheable() to return false for every request.
Symptoms:
- All pages return X-LiteSpeed-Cache-Control: no-cache
- LiteSpeed debug log shows not cacheable before ctrl finalize on every request
- No pages are ever stored in the OLS cache
- High PHP memory usage as every request hits origin (no cache hits)
Verification:
With WooCommerce 10.6.1 active, DONOTCACHEPAGE is always defined as true by the time LiteSpeed's Control::finalize() runs at shutdown. Removing WooCommerce's hook manually confirms this is the cause — with the hook removed, DONOTCACHEPAGE remains undefined and pages cache correctly with public,max-age=604800.
Workaround:
Add the following to a must-use plugin:
php<?php
/**
* Fix WooCommerce 10.1+ prevent_caching conflict with LiteSpeed Cache.
*/
add_action('init', function() {
remove_action('wp_headers', ['WC_Cache_Helper', 'prevent_caching'], 5);
}, 1);
Expected fix:
thirdparty/woocommerce.cls.php should be updated to remove or override WooCommerce's wp_headers hook when LiteSpeed Cache is handling cache control, similar to how it previously overrode the wp action hook. LiteSpeed Cache's own WooCommerce compat layer already correctly handles cart/checkout/account page exclusions — the blanket wp_headers hook from WooCommerce should not be allowed to override it.
Environment:
Description:
Since WooCommerce 10.1.0, WC_Cache_Helper::prevent_caching() was moved from the wp action to the wp_headers filter at priority 5 (see comments in code). This change causes LiteSpeed Cache to never cache any pages on WooCommerce stores.
Root cause:
WooCommerce's prevent_caching() now fires on wp_headers unconditionally for every page load, calling set_nocache_constants() which defines DONOTCACHEPAGE = true. LiteSpeed Cache's WooCommerce compatibility handler (thirdparty/woocommerce.cls.php) was written to handle the old wp action hook and does not override the new wp_headers hook. As a result, DONOTCACHEPAGE is always true before LiteSpeed finalises cache control, causing Control::is_cacheable() to return false for every request.
Symptoms:
Verification:
With WooCommerce 10.6.1 active, DONOTCACHEPAGE is always defined as true by the time LiteSpeed's Control::finalize() runs at shutdown. Removing WooCommerce's hook manually confirms this is the cause — with the hook removed, DONOTCACHEPAGE remains undefined and pages cache correctly with public,max-age=604800.
Workaround:
Add the following to a must-use plugin:
Expected fix:
thirdparty/woocommerce.cls.php should be updated to remove or override WooCommerce's wp_headers hook when LiteSpeed Cache is handling cache control, similar to how it previously overrode the wp action hook. LiteSpeed Cache's own WooCommerce compat layer already correctly handles cart/checkout/account page exclusions — the blanket wp_headers hook from WooCommerce should not be allowed to override it.