Verification: a143cc29221c9be0

Php check browser cookie enabled

Php check browser cookie enabled

Common Issues and Solutions¶

Here is a list of common problems that people report with the LiteSpeed Cache plugin for WordPress and/or the services. If you have one of these issues, click the link and learn how to solve it.

  • How to tell if your site is being cached
  • How to exclude a page from cache
  • How to verify that an excluded page is not being cached
  • What to do if your site appears "broken" when LSCache is enabled
  • What to do if your site appears "broken" when a CDN is connected
  • What to check if you can't save any options in WP-Admin
  • What to do if Image Optimization won't start
  • What to do if WebP images are not being generated
  • What to do if WebP images are not replacing JPEGs and PNGs
  • How to tell if CDN is working
  • What to do if your site is in an incorrect free quota tier

If you don't find your issue in this list, you can check out the rest of our LSCWP Documentation or the Knowledgebase.

If you need to request assistance, please post a WordPress Support Forum topic or open a support ticket. Be sure to share your Report Number so we may assist you more quickly.

First Steps¶

Verify it's an LSCache Issue¶

  1. LSCache plugin should be activated
  2. LSCache should be enabled
  3. Navigate to LiteSpeed Cache > Toolbox > Debug Settings and set Disable All Features to ON

Are you still having a problem? Then it is not an LSCache plugin issue.

Is the issue gone? Then the issue is probably related to the LSCache plugin.

Check your LSCWP Version¶

Our LSCWP plugin is developed at a very fast pace. Some compatibility issues with other plugins may have already been fixed in the latest version. You should always upgrade to the latest version before spending resources on any issue.

Pinpoint the Problem¶

By default, LiteSpeed Cache does not apply any optimizations, and does not alter any page content (unless you have ESI enabled). So, it is likely that one of the settings you have enabled has caused the issue. In order to pinpoint that setting, the first thing you'll need to do is go back to the defaults:

  1. Export your current settings as a backup
  2. Reset LSCache to its default settings

If the site is still broken with the default settings, please contact our support team. However, if the site works fine with the default settings, that confirms that an option you had enabled is causing the issue.

In order to find the problematic setting, you must re-enable each of your previous settings one-by-one until you find the one that breaks your site.

With each new setting you enable, be sure to Purge All, and refresh the browser. When the issue comes back, you know you've found the problematic setting.


Purge All does not purge Critical CSS or Low-Quality Image Previews. If you are testing features related to CCSS and LQIP you will also need to Purge All - Critical CSS and Purge All - LQIP Cache, respectively.

When you begin re-enabling settings, the following rules of thumb can help you decide the best place to start:

  • If certain functionality or buttons have stopped working, it's likely an issue with JavaScript Optimization.
  • If pages are rendering badly, then it's likely an issue with CSS Optimization.
  • If images aren't loading properly, then it's likely an issue with Media Optimization.

Get a Report Number¶

If you have been through this Troubleshooting Guide, and you still require support, we may ask to see your Environment Report. The Environment Report tells us what settings you have enabled, what other plugins you have installed, and the contents of your .htaccess file, among other useful things.

To generate and share your Environment Report, navigate to LiteSpeed Cache > Toolbox > Report, scroll down and press the Send to LiteSpeed button. Make note of the Report Number that is generated, and include it in your support request so that we may look it up on our end.

Turn On the Debug Log¶


See a video demonstration of Debug LSCWP with the Debug Log here.

In some situations, it may be helpful to see the WordPress debug log. Because it has the potential to take up a lot of disk space, debug logging is disabled by default. To enable it, modify wp-config.php under WordPress' root directory as follows:

  1. Set WP_DEBUG to true: define('WP_DEBUG',true);
  2. Add the following: define('WP_DEBUG_LOG',true);

A debug.log file will be generated under the wp-content directory, and will log information whenever WordPress hits the backend.

You can monitor this log during debugging using the following command:

tail -f wp-content/debug.log

Be sure to disable logging when you no longer need it.

LiteSpeed Cache is Disabled¶

If you see a warning that indicates LiteSpeed Cache is disabled, the warning itself may give a clue as to the source of the problem.

Disabled at Server Level¶

The LSCache Module is disabled at the server level

This indicates that cache is turned off at the highest level. You will need to configure your server, or have your hosting provider do it for you.

Disabled in Plugin Settings¶

LiteSpeed Cache is disabled in the plugin settings

This indicates that you haven't turned on caching in the plugin settings. Do so, and the problem should be solved.

Just Plain Disabled¶

LiteSpeed Cache is disabled

This is a generic error that doesn't indicate any cause. Navigate to LiteSpeed Cache > Toolbox > Report and look at the Report Summary. The Server Variables section right at the top can give you some helpful information. Check the value of LITESPEED_ON. It should be true.

If this value is NULL, it means that you are not running with LiteSpeed Web Server. This is allowed, but it limits the functions that you are able to use. Learn more.

WordPress Lacks Permissions¶

If WordPress doesn't have access to create tables in your database, please run these SQL queries manually after installation:

CREATE TABLE IF NOT EXISTS wp_litespeed_optimizer (
hash_name varchar(60) NOT NULL COMMENT hash.filetype,
src text NOT NULL COMMENT full url array set,
dateline int(11) NOT NULL,
refer varchar(255) NOT NULL COMMENT The container page url,
UNIQUE KEY hash_name (hash_name),
KEY dateline (dateline)


CREATE TABLE IF NOT EXISTS `wp_litespeed_img_optm` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `post_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `optm_status` varchar(64) NOT NULL DEFAULT '',
  `src` varchar(1000) NOT NULL DEFAULT '',
  `srcpath_md5` varchar(128) NOT NULL DEFAULT '',
  `src_md5` varchar(128) NOT NULL DEFAULT '',
  `server` varchar(255) NOT NULL DEFAULT '',
  `root_id` int(11) NOT NULL DEFAULT '0',
  `src_filesize` int(11) NOT NULL DEFAULT '0',
  `target_filesize` int(11) NOT NULL DEFAULT '0',
  `target_saved` int(11) NOT NULL DEFAULT '0',
  `webp_filesize` int(11) NOT NULL DEFAULT '0',
  `webp_saved` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `post_id_2` (`post_id`,`srcpath_md5`),
  KEY `post_id` (`post_id`),
  KEY `optm_status` (`optm_status`),
  KEY `root_id` (`root_id`),
  KEY `src_md5` (`src_md5`),
  KEY `srcpath_md5` (`srcpath_md5`)


If your site uses a table prefix other than wp_, please replace the wp_ in wp_litespeed_optimizer and wp_litespeed_img_optm with your site's prefix.

Unable to Save Changes in WP-Admin¶

If you are unable to save your settings in WP-Admin, or the options are reset to their previous state after refreshing the page, there are a few possible explanations.

Accidental Caching¶

WP-Admin may be cached by LiteSpeed Cache or by browser cache. To see if this is the case, check the response headers, like so:

!Page is not cached

  1. From a non-logged-in browser, navigate to the page, open the Network tab in the developer tools, refresh the page, and click the first listed resource. This should be the URI of the page, as described above.
  2. Look for the X-LiteSpeed-Cache-Control: no-cache header. If you find it, then the page has successfully not been served via LSCache. If the header is set to miss or hit, then LiteSpeed Cache is caching the admin page. Please check with your system administrator to be sure that Enable Public Cache is not set to Yes in the LiteSpeed WebAdmin Console.
  3. Look for two headings:
    • cache-control: no-cache, must-revalidate, max-age=0
    • expires: Wed, 11 Jan 1984 05:00:00 GMT (the value may be set to any date prior to today) If either of those headers is not present, or has a different value, the browser is likely caching your page. Typically, browser caching is accidentally enabled via bad optimization rules that add the cache control header to dynamic requests. Check your .htaccess file to fix this.
  4. If you have opcache enabled, please disable it and see if that helps. You can use the phpinfo page to verify.
  5. If you have an additional cache layer, particularly object cache with Redis or Memcached, please try disabling that.

Database Corruption¶

If the LiteSpeed Cache plugin's database structure is corrupted or damaged, it could cause this behavior. It's rare that this will happen, but if it does, you may repair it with the following steps:

  1. Back up your current database.
  2. Disable the LiteSpeed Cache plugin.
  3. Create a PHP file named repair.php in same directory as your wp-config.php. Copy the following contents into repair.php:
    prefix . 'options';
    $table_name = "{$wpdb->prefix}options";
    $wpdb->query( $wpdb->prepare( "DELETE FROM `$table_name` WHERE `option_name` like '%litespeed.%' " ) );
    if ( defined( 'LSCWP_V' ) ) {
    do_action( 'litespeed_purge_all' );
    echo "done";
  4. Visit, replacing with your actual domain. It should output "done."
  5. Delete repair.php, and re-enable the LiteSpeed Cache plugin. The database will be freshly created, and should work fine now.

Admin Bar is Missing¶

The Admin Bar at the top of the page should display on the frontend for logged in users.

Immediately after logging in, if the admin bar does not display until you manually refresh the page, this could be due to the Instant Click setting.

Here's why: When you enable Instant Click via LiteSpeed Cache > Cache > Advanced, some themes (e.g., dService, Blocksy, and more) will prefetch the home page content before logging you in. As a result, the prefetched version from browser cache does not include the admin bar.

To verify that this is what is happening, turn on the browser developer tools, check the HTTP response header for the login page request. Make sure the Disable Cache option in the tool is not selected. The HTTP response header should show the status code 200 with (from Prefetch Cache) appended. If you see this, it confirms that Instant Click is the problem.

Solution: Turn off Instant Click when using an incompatible theme.


This behavior occurs with Chrome and Microsoft Edge, but not Firefox.

Caching Issues¶

Forced Caching¶

Sometimes, in an effort to make sure that certain pages are always cached, you erroneously force the entire site to be cached. This is not a good idea, because you never know when there will be individual exceptions to caching.

Navigate to LiteSpeed Cache > Cache > Cache and look in the Force Cache URIs box. If you see / or * there, then you will need to remove it. Save, and then Purge All LSCache.

Logged-in Users Appearing as Logged-out¶

This problem is caused when using multiple web applications under a single domain. You can find more information on this issue and how to resolve it in our Handling Logged-in Cookie Conflicts documentation.

Cache Always Misses¶

If you always see X-LiteSpeed-Cache: miss in the headers, then something is wrong. See if any of the following steps help:

  • Disable and then re-enable LSCache.
  • Verify that the cache directory has the proper permissions (0755). If you don't know your cache root directory, your hosting provider can help.
  • Some CDNs have cache settings that can break LSCache and cause X-LiteSpeed-Cache: miss to appear at all times. However, accessing the backend server directly achieves X-LiteSpeed-Cache: hit. If this happens, turn off the CDN's cache functions.

Browser Displays Stale Content¶

Older cached versions of updated pages are being served. We've checked the response headers for the X-LiteSpeed-Cache line, and it is not found. This indicates that the page is not coming from LiteSpeed's cache, even though it should be.


The page is being served from the browser cache due to cache rules present in .htaccess (most likely in the WordPress root directory).

If .htaccess contains an ExpiresDefault cache rule, or an ExpiresByType text/html cache rule that is not set to 0 seconds, the copy stored by the browser cache will be served. The page will never be requested from LiteSpeed. Because the browser cache lacks the advanced purging rules that are the backbone of LiteSpeed's accuracy, this can result in stale content being served.


If you have no other cache plugins installed, and you have no interest in using a browser cache, then you can safely remove any of the ExpiresDefault or ExpiresByType lines.

If you want to leave the existing browser caching functionality in place, you'll need to specifically exclude the pages that are handled by LiteSpeed Cache. Add the following line above the ExpiresDefault line:

    ExpiresByType text/html "access plus 0 seconds"

If the ExpiresByType text/html rule already exists, edit it so that it matches the line above.

This rule will make it so that the pages that are cached by LSCWP are not included in the browser cache, but any other browser-cache behavior will remain unchanged.

PHP Session Issues¶

Some plugins, such as WHMpress, that use PHP Session to store values (currency, language...etc) don't work with LiteSpeed Cache. Once LiteSpeed Cache is enabled, user-dependent values like currency do not work or display correctly.


Pages whose content depends on PHP Session are not cache-friendly. Once the cached page is generated, it will not vary on session data.

Why? LiteSpeed Cache is designed to avoid hitting the PHP backend. Therefore, there is no way for the cache module to know what value is stored in PHP Session for any visitor other than the first one to load the page.


To make this to work, a code change to the third party plugin is required. The developer can change the plugin to store the value in a cookie and then LiteSpeed Cache can be set to vary on that cookie.

Cache Purges Too Frequently¶

Cache is getting purged quite often, inconsistent with the TTL settings. Some actions may unintentionally trigger a purge, and it may be necessary to do some investigation to find the culprit.

Possible Explanations¶

  1. LiteSpeed Cache > Cache > Purge: Have you enabled All pages, and you post frequently?
  2. LiteSpeed Cache > Cache > Purge: Have you manually added any hooks to Purge All Hooks?
  3. Do you have any plugins that are automatically enabled or disabled when a page loads?

All of these things will cause a Purge All action. If you can disable any of them, that should solve the problem.

Diagnosing the Problem¶

If the cause is not obvious, you'll need to do a little digging. Enable the debug log, repeat the steps that cause a purge, disable logging, and then check the log to find the cause of any Purge All actions.

Enable LSCWP Debug Log¶

Enable the Debug Log, chosing Admin IP only, add your IP under Admin IPs, and set Debug Level to Advanced.


Reproduce the Issue¶

Execute the following steps:

  • Purge All - LSCache
  • Access any page twice
  • Make sure the cache header is showing hit
  • Reproduce the steps that are suspected of triggering a purge.

In this example, let's assume you have noticed unusual purging activity when you edit a WooCommerce product's inventory. The steps your would reproduce in this case are: visit home page, edit product, visit home page again.

Check the Debug Log¶

LiteSpeed Cache is a tag-based caching system, so in order to figure out what is happening, you should search for the appropriate tags in the debug log. First, we look for X-LiteSpeed-Tag to find the pages that are impacted. We find the following lines, which correspond to home page, edit product, home page:

X-LiteSpeed-Tag: 87f1_URL.6666cd76f96956469e7be39d750cc7d9,87f1_F,87f1_Po.24,87f1_PGS,87f1_
X-LiteSpeed-Tag: 87f1_tag_priv,public:87f1_ESI,public:87f1_ESI.admin-bar,public:87f1_
X-LiteSpeed-Tag: 87f1_URL.6666cd76f96956469e7be39d750cc7d9,87f1_F,87f1_Po.24,87f1_PGS,87f1_

Then we search for X-LiteSpeed-Purge to find the purge action. We find the following lines:

X-LiteSpeed-Purge: public,87f1_WC_T.18
X-LiteSpeed-Purge: public,87f1_WC_T.18,87f1_Po.37,87f1_URL.c5058f4b6fbb3ed974efbe319a954e61,87f1_W.recent-posts-2,87f1_T.2,87f1_T.9,87f1_T.18,87f1_A.1,87f1_PT.product,87f1_F,87f1_H,87f1_PGS,87f1_PGSRP,87f1_D.201806
X-LiteSpeed-Purge: public,87f1_WC_T.18,87f1_Po.37,87f1_URL.c5058f4b6fbb3ed974efbe319a954e61,87f1_W.recent-posts-2,87f1_T.2,87f1_T.9,87f1_T.18,87f1_A.1,87f1_PT.product,87f1_F,87f1_H,87f1_PGS,87f1_PGSRP,87f1_D.201806,87f1_REST
X-LiteSpeed-Purge: public,stale,87f1_WC_T.18,87f1_Po.37,87f1_URL.c5058f4b6fbb3ed974efbe319a954e61,87f1_W.recent-posts-2,87f1_T.2,87f1_T.9,87f1_T.18,87f1_A.1,87f1_PT.product,87f1_F,87f1_H,87f1_PGS,87f1_PGSRP,87f1_D.201806,87f1_REST,87f1_WC_T.9
X-LiteSpeed-Purge: public,stale,87f1_WC_T.18,87f1_Po.37,87f1_URL.c5058f4b6fbb3ed974efbe319a954e61,87f1_W.recent-posts-2,87f1_T.2,87f1_T.9,87f1_T.18,87f1_A.1,87f1_PT.product,87f1_F,87f1_H,87f1_PGS,87f1_PGSRP,87f1_D.201806,87f1_REST,87f1_WC_T.9

Here's how it works: if the tag(s) in X-LiteSpeed-Purge is/are contained in the X-LiteSpeed-Tag of other pages, then those other pages will be purged during the action.

Now let's check the above tags. We will see:

87f1_F and 87f1_PGS are contained by the homepage, so it gets purged. 87f1 is the prefix. F stands for Front Page, and PGS stands for Pages. You can see a full list of tag classes in the code, if you wish.


F and PGS are triggered by the setting Auto Purge Rules For Publish/Update. If you do not want the Front page or Pages to be purged every time you update a WooCommerce item, then you need to uncheck those options.



If you see the PGSRP tag, that is for the Recent Posts Widget. You can uncheck the all pages with Recent Posts Widget setting in the auto purge rules, to keep it from purging every page on your site. If you still want to keep the widget itself updated, enable ESI for the site, enable ESI for the Recent Posts Widget, and set it to Public. That will keep the widget updated for new posts, but won't require every page it is on to be purged.


Page Content Not Updating Correctly¶

If your site uses a plugin that updates the content of a page without editing/saving that page, such as a "like" button that updates a counter when pressed using ajax, LSCache will not be made aware that the page should be purged from cache. As long as the now outdated copy of the page is still in cache and being served, it will appear like these changes never happened.


Add our litespeed_purge_post($pid) API call to the offending plugin to have it notify LSCache that the page should be purged.


  1. Purge the cache and with the inspector open (right click page > Inspect) access the page as a guest/non-logged in user.
  2. In the inspector, click into the Network tab and select the page request - this is usually the first entry. With this selected, click the Header tab and check that the Response Header does not contain X-LiteSpeed-Cache: hit.
  3. (If your plugin updates on each visit, skip this step) Refresh the page. You should now see X-LiteSpeed-Cache: hit in your response header. This indicates that the page was served from cache.
  4. Trigger your plugin and make sure that the page is updated as expected.
  5. Refresh the page one last time. X-LiteSpeed-Cache: hit should once again be gone from the Response Header and the page should still contain the updated information.

WP-Cron Issues¶

A Scheduled Event has Failed¶

The following notice may appear in the Health Check plugin: The scheduled event, litespeed_xxxx[image or ccss]_trigger, failed to run, Your site still works, but this may indicate that scheduling posts or automated updates may not work as intended

For example:

The scheduled event, litespeed_imgoptm_trigger, failed to run.

Technically, this is not a LiteSpeed issue, but is due to WordPress itself. This usually happens when WP does a version update. It will usually clear up on its own in a day or so, once the WP-Cron is back to normal.

If you don't want to wait, you can disable WP-Cron and use a 3rd party cron like cPanel cron.

Scheduled Posts Not Publishing On Time¶

Scheduled Posts are published in WordPress through a WP-Cron job. Normally, WordPress triggers the cron job each time a request hits the backend. The backend is rarely hit, however, when using a cache, and this causes scheduled posts to publish late.

LSCWP will correctly purge the cache when a scheduled post is published in the cron job. All you need to do is make sure that you can reliably hit the backend. This can be done by scheduling a cron job to hit wp-cron.php at your ideal interval.

For Example, to update scheduled posts every 15 minutes:

    */15 * * * * wget http://your_wp_site/wp-cron.php

When using a server level cron job, WordPress suggests defining DISABLE_WP_CRON in your wp-config.php file to disable checking WP-Cron on a backend hit.

    define('DISABLE_WP_CRON', true);

This may be useful in reducing the number of calls made to WP-Cron if that is desired.

For a more in-depth discussion of this issue, see our blog.

WP-Cron PHP Timing Out¶

Some WordPress plugins or operations may need to run very long PHP proceses, but they may be killed by LiteSpeed Web Server with error 500 after 120 seconds. With that in mind, we have additional environment variables that will resolve that issue.


You can use the noconntimeout variable in the htaccess file. Exlude WP-Cron with this rule:

    RewriteEngine On
    RewriteRule (wp-cron).php - [E=noconntimeout:1]


You can use the SetEnv/SetEnvIf variable too, but we recommend using it only in a vhost file.

    SetEnv Request_URI "(wp-cron).php" noabort noconntimeout

For additional examples and information on how to configure the server, you can see this wiki.

Both of these variables will allow you to run PHP processes with no limits for the web pages affected by this .htaccess file.

Third Party Plugin Issues¶

Currency/Language Switcher Plugins¶

Because these plugins are mostly PHP session-based, there's no way to fix the caching on our end. The plugin author needs to change their code to be compatible with LSCache. See the API for more information on how to do that.

If you have EU Cookie Consent on your site, you will need a cache vary. Varying on the cookie allows two versions of each page to be stored in cache - one for people who have consented to the cookie, and one for those who have not yet done so.

Add the following line to .htaccess:

RewriteRule .* - [E=Cache-Vary:%{ENV:LSCACHE_VARY_VALUE}+euCookie]

Some plugins, such as the YITH WooCommerce Wishlist plugin, are incompatible with LSCache for WordPress. The simplest way to avoid cache-related problems with them is to exclude their pages from cache entirely.


If a plugin is cookie-based, you need only add the plugin's specific cookie to LiteSpeed Cache's Exclude settings.


From the WordPress Dashboard, navigate to LiteSpeed Cache > Cache > Excludes. Scroll down to Do Not Cache Cookies and enter plugin_cookie in the box. Be sure to replace "plugin_cookie" with the actual name of the plugin's cookie, as shown in the image. If you are excluding multiple cookies in this setting, make sure each cookie has its own line.


We have some known incompatible plugins on our development to-do list. We intend to fix LSCache compatibility with these plugins eventually, but for now we have set up LSCache to automatically set them to Do Not Cache.

If you are using one of these plugins, you do not have to use the manual steps above! LSCache will automatically exclude them from cache.

  1. Woocommerce Wish List
  2. WP Poll

What is Cookie?

A cookie is a small file with the maximum size of 4KB that the web server stores on the client computer.

Once a cookie has been set, all page requests that follow return the cookie name and value.

A cookie can only be read from the domain that it has been issued from. For example, a cookie set using the domain can not be read from the domain

Most of the websites on the internet display elements from other domains such as advertising. The domains serving these elements can also set their own cookies. These are known as third party cookies.

A cookie created by a user can only be visible to them. Other users cannot see its value.

Most web browsers have options for disabling cookies, third party cookies or both.

If this is the case then PHP responds by passing the cookie token in the URL.

The diagram shown below illustrates how cookies work.


1) A user requests for a page that stores cookies

2) The server sets the cookie on the user’s computer

3) Other page requests from the user will return the cookie name and value

In this tutorial, you will learn-

  • Why and when to use Cookies?
  • Creating Cookies
  • Retrieving the Cookie value
  • Delete Cookies
  • What is a Session?
  • Why and when to use Sessions?
  • Creating a Session
  • Destroying Session Variables

Why and when to use Cookies?

  • Http is a stateless protocol; cookies allow us to track the state of the application using small files stored on the user’s computer.

    The path were the cookies are stored depends on the browser.

    Internet Explorer usually stores them in Temporal Internet Files folder.

  • Personalizing the user experience – this is achieved by allowing users to select their preferences.

    The page requested that follow are personalized based on the set preferences in the cookies.

  • Tracking the pages visited by a user

Creating Cookies

Let’s now look at the basic syntax used to create a cookie.


  • Php“setcookie” is the PHP function used to create the cookie.
  • “cookie_name” is the name of the cookie that the server will use when retrieving its value from the $_COOKIE array variable. It’s mandatory.
  • “cookie_value” is the value of the cookie and its mandatory
  • “[expiry_time]” is optional; it can be used to set the expiry time for the cookie such as 1 hour. The time is set using the PHP time() functions plus or minus a number of seconds greater than 0 i.e. time() + 3600 for 1 hour.
  • “[cookie_path]” is optional; it can be used to set the cookie path on the server. The forward slash “/” means that the cookie will be made available on the entire domain. Sub directories limit the cookie access to the subdomain.
  • “[domain]” is optional, it can be used to define the cookie access hierarchy i.e. means entire domain while limits the cookie access to and its sub domains. Note it’s possible to have a subdomain of a subdomain as long as the total characters do not exceed 253 characters.
  • “[secure]” is optional, the default is false. It is used to determine whether the cookie is sent via https if it is set to true or http if it is set to false.
  •  “[Httponly]” is optional. If it is set to true, then only client side scripting languages i.e. JavaScript cannot access them.

Note: the php set cookie function must be executed before the HTML opening tag.

Let’s now look at an example that uses cookies.

We will create a basic program that allows us to store the user name in a cookie that expires after  ten seconds.

The code below shows the implementation of the above example “cookies.php”.


the cookie has been set for 60 seconds

Retrieving the Cookie value

Create another file named “cookies_read.php” with the following code.


Array ( [PHPSESSID] => h5onbf7pctbr0t68adugdp2611 [user_name] => Guru99 )

  Note: $_COOKIE is a PHP built in super global variable.

It contains the names and values of all the set cookies.

The number of values that the

$_COOKIE array can contain depends on the memory size set in php.ini.

The default value is 1GB.

Testing our application.

Let’s assume you have saved your PHP files in phptus folder.

  • Step 1 – open your web browser and enter the URL http://localhost/phptuts/cookies_read.php

Note: Only an empty array has been displayed

  • Step 2 – Browser to the URL http://localhost/phptuts/cookies.php

  • Step 3 – Switch back to the first tab then click on refresh button

Wait for a minute then click on refresh button again. What results did you get?

Delete Cookies

  • If you want to destroy a cookie before its expiry time, then you set the expiry time to a time that has already passed.
  • Create a new filed named cookie_destroy.php with the following code
  • Repeat steps 1 through to 3 from the above section on retrieving cookie values.
  • Open the URL http://localhost/phptuts/cookie_destroy.php
  • Switch to the URL http://localhost/phptuts/cookies_read.php what results does it display?

What is a Session?

  • A session is a global variable stored on the server.
  • Each session is assigned a unique id which is used to retrieve stored values.
  • Whenever a session is created, a cookie containing the unique session id is stored on the user’s computer and returned with every request to the server.  If the client browser does not support cookies, the unique php session id is displayed in the URL
  • Sessions have the capacity to store relatively large data compared to cookies.
  • The session values are automatically deleted when the browser is closed. If you want to store the values permanently, then you should store them in the database.
  • Just like the $_COOKIE array variable, session variables are stored in the $_SESSION array variable. Just like cookies, the session must be started before any HTML tags.

Why and when to use Sessions?

  • You want to store important information such as the user id more securely on the server where malicious users cannot temper with them.
  • You want to pass values from one page to another.
  • You want the alternative to cookies on browsers that do not support cookies.
  • You want to store global variables in an efficient and more secure way compared to passing them in the URL
  • You are developing an application such as a shopping cart that has to temporary store information with a capacity larger than 4KB.

Creating a Session

In order to  create a session, you must first call the PHP session_start function and then store your values in the $_SESSION array variable.

 Let’s suppose we want to know the number of times that a page has been loaded, we can use a session to do that.

The code below shows how to create and retrieve values from sessions


You are visitor number 1

Destroying Session Variables

The session_destroy() function is used to destroy the whole Php session variables.

If you want to destroy only a session single item, you use the unset() function.

The code below illustrates how to use both methods.

  Session_destroy removes all the session data including cookies associated with the session.

Unset only frees the individual session variables.

Other data remains intact.

What is Cookie Testing?

Cookie Testing is defined as a Software Testing type that checks Cookie created in your web browser. A cookie is a small piece of information that is stored in a text file on user's (client) hard drive by the web server. This piece of information is then sent back to the server each time the browser requests a page from the server. Usually, cookie contains personalized user data or information that is used to communicate between different web pages. The screen-shot below shows cookies for different websites.

In other words, cookies are nothing but a user's identity and used to track where the user navigated throughout the pages of the website. The purpose of a cookie is to make rapid interaction between users and websites. Applications, where cookies can be used, is to implement a shopping cart, personalized web experience, user tracking, marketing, user sessions etc.

In this tutorial, we will learn

  • What is the Content of Cookie?
  • Types of Cookies
  • Where Cookies are stored?
  • How to test Cookies – Sample Test Cases
  • Plugins to Test Cookies
  • Cookie Modification in Action
  • Difference between Cookie and Session

What is the Content of Cookie?

The cookie consists of mainly three things

  1. The name of the server the cookie was sent from
  2. Cookies Lifetime
  3. A value. This is usually a randomly generated unique number

Types of Cookies

Usually, there are two types of cookies written on user machines

  • Session Cookies: These cookies are active till the browser that triggers the cookie is open. When we close the browser this session cookie gets deleted

  • Persistent Cookies: These cookies are written permanently on the user machine and it lasts for months or years

Where Cookies are stored?

When any web page application writes a cookie, it is stored in a text file on user hard disk drive. The path where the cookies are saved depends on the browser. Different browsers store cookie in different paths.

For example, in Mozilla Firefox browser you can see the cookies in browser options. To view this click on Tools -> Options -> Privacy and then click on "Remove Individual Cookies".

While in Internet Explorer browser it stores cookies on path "C:\Documents and Settings\Default User\Cookies"

How to test Cookies

Following is an important checklist and steps on How to test Cookies in website :

  1. Disabling cookies: Disable all cookies and attempt to use the site's major functions
  2. Corrupting cookies: Manually edit the cookie in notepad and change the parameters with some random values
  3. Cookies encryption: Sensitive information like passwords and usernames should be encrypted before it is sent to our computer
  4. Cookie testing with multiple browsers: Check your website page is writing the cookies properly on a different browser as expected
  5. Checking the deletion from your web application page
  6. Selectively rejecting cookies: Delete all the cookies for the websites and see how the website reacts to it
  7. Access to cookies: Cookies written by one website should not be accessible by others
  8. No overuse of cookies: If the application under test is a public website, there should not be overuse of cookies
  9. Testing with the different setting: Testing should be done properly to check that website is working well with different cookie setting
  10. Categorize cookies separately: Cookies should not be kept in the same category of the viruses, spam or spyware

How to test Cookies

Following is an important checklist and steps on How to test Cookies in website :

  1. Disabling cookies: Disable all cookies and attempt to use the site's major functions
  2. Corrupting cookies: Manually edit the cookie in notepad and change the parameters with some random values
  3. Cookies encryption: Sensitive information like passwords and usernames should be encrypted before it is sent to our computer
  4. Cookie testing with multiple browsers: Check your website page is writing the cookies properly on a different browser as expected
  5. Checking the deletion from your web application page
  6. Selectively rejecting cookies: Delete all the cookies for the websites and see how the website reacts to it
  7. Access to cookies: Cookies written by one website should not be accessible by others
  8. No overuse of cookies: If the application under test is a public website, there should not be overuse of cookies
  9. Testing with the different setting: Testing should be done properly to check that website is working well with different cookie setting
  10. Categorize cookies separately: Cookies should not be kept in the same category of the viruses, spam or spyware

Plugins for Cookie Test

Modern browsers allow viewing/editing of the cookies in the browser itself. There are cookie tester plugins in Mozilla and Google Chrome both.

  1. Chrome Cookie Manager
  1. For Google Chrome browser: Edit This Cookie

Cookie Modification in Action

We will use edit the cookie plugin for Chrome.

Step 1)

Enter the userID & password to login into the Guru99 bank.

Step 2)

Click on the plugin icon and it will open another window as shown below

Step 3)

Change the value of the cookie to "guru99" and then click on to save the changes

Testing tips

Enable the new SameSite behavior

To ensure that you are testing against the correct browser behavior, you must first ensure that the new SameSite behavior is enabled. As of Chrome 85, the new behavior is enabled by default in Chrome, so you only need to make sure that the features are not explicitly disabled by your flags settings. (NOTE: These flags were removed in Chrome 91, as the behavior is enabled by default as of Chrome 85. If you are running Chrome 91 or newer, you can skip to step 3.)

  1. Go to chrome://flags and enable (or set to "Default") both #same-site-by-default-cookies and #cookies-without-same-site-must-be-secure.

  2. Restart Chrome for the changes to take effect, if you made any changes.

  3. Verify that your browser is applying the correct SameSite behavior by visiting this test site and checking that all rows are green.

Chrome 84 introduces a flag called #enable-experimental-cookie-features, which enables a group of new and upcoming cookie features, including #same-site-by-default-cookies and #cookies-without-same-site-must-be-secure. This flag also removes the 2 minute "Lax+POST" exception for top-level cross-site POST requests. This can be a convenient way to preview the future behavior of cookies in Chrome, but it may also result in unexpected behavior as the set of cookie features enabled by this flag is subject to change.

Testing your site

Thoroughly test site functionality, with a focus on anything involving federated login flows, online payments, 3-D Secure verification, multiple domains, or cross-site embedded content (iframes, images, videos, etc.).

For any flows involving POST requests (such as some login flows), we recommend that you test with and without a long (> 2 minute) delay, due to the 2 minute threshold for Lax+POST behavior (see below for more Lax+POST tips).

You will know if cookies used on your site will be affected by the new SameSite behavior if you see a banner in DevTools about issues detected while testing your site, and clicking on the banner takes you to one or more issues related to SameSite. Issues can also be viewed directly in the Issues tab, found in the three-dot menu in DevTools labeled "More tools". From the Issues tab, you can view the cookies triggering each warning by clicking on "affected resources".

Note that the presence of a cookie in an issue does not necessarily indicate that something is broken -- you must test thoroughly and determine that for yourself. Some of those blocked cookies may not affect any site functionality. Some "legacy" cookies are also intentionally left non-compliant as a workaround for incompatible clients, and will continue to appear in the Issues tab despite the site having been updated.

Testing under Lax+POST

If your site does not use POST requests, you can ignore this section.

Firstly, if you are relying on top-level, cross-site POST requests with cookies then these will only be sent if they specify SameSite=None; Secure. Also consider the POST/Redirect/GET pattern as a way of removing the need for the cookie on that request. Under the new SameSite behavior, any cookie that was not set with a specified SameSite attribute value will be treated as SameSite=Lax by default, which will exclude cookies from these requests. However there is the “Lax+POST” special exception that Chrome makes for such cookies for the first 2 minutes after they are created, which allows them to be sent on top-level cross-site POST requests (which normal Lax cookies are excluded from). This special exception for fresh cookies will be phased out in future Chrome releases.

When testing, you should pay special attention to any requests that require cross-site POST requests (such as some login flows). If a cookie was granted Lax+POST due to its age ( 2 min) delay between setting the cookie and making the POST request.

We also recommend testing with the eventual SameSite behavior (after Lax+POST is phased out). To do this, run Chrome from the command line with the additional flag --enable-features=SameSiteDefaultChecksMethodRigorously to disable the Lax+POST exception. (This is automatically applied if you enabled the SameSite behavior via the #enable-experimental-cookie-features flag.)

For automated testing, it may be impractical to wait for 2 minutes to test the long-delay behavior. For this purpose, you can use the command line flag --enable-features=ShortLaxAllowUnsafeThreshold to lower the 2 minute threshold to 10 seconds.

Testing Chrome extensions

Chrome extensions must also abide by the new SameSite cookie behavior. Extension pages, which have a chrome-extension:// scheme URL, are generally considered cross-site to any web page (https:// or http://). There are certain scenarios where an exception is made (this is accurate as of Chrome 80, but behavior may change in the future):

  • If an extension page initiates a request to a web URL, the request is considered same-site if the extension has host permission for the requested URL in the extension’s manifest. This could happen, for example, if an extension page has an iframe embedding a site that the extension has host permission for.

  • If the top level frame (i.e. the site shown in the URL bar) is an extension page, and the extension has host permission for the requested URL, and the requested URL and the initiator of the request are same-site to each other, and the extension has host permission for the initiator origin, then the request is considered same-site. For example, this could happen if an extension has host permission for “*://*.site.example/”, and an extension page loads in an iframe, which then navigates to

The chrome.cookies API is able to read and set any kind of cookie, including SameSite cookies. However, a web page embedded in an extension page is considered to be in a third party context for the purposes of document.cookie (JavaScript) accesses. For content scripts, the behavior of SameSite cookies is exactly the same as if the request were initiated from the page on which the content script is running.

If your extension embeds a web page on an extension page, we recommend testing that the necessary cookies are sent on the web request. Blocked cookies should emit warning messages in the DevTools console for the extension page. If the special exceptions above apply, no message will appear.

Something is broken! -- Debugging tips

The basics

You should suspect SameSite as the underlying problem if your site makes requests to other domains in embedded contexts (such as embedded images/videos/social posts, widgets from other sites, etc.), makes POST requests cross-site (such as in some login and payment flows), fetches cross-site resources via JavaScript, or otherwise accesses cookies across sites. If the issue is primarily a browser or tab crashing or hanging, it is less likely to be caused by the new SameSite cookie behavior.

First, check if the problem persists after setting the SameSite flags above to “Disabled” (note: setting them to “Default” may or may not disable the features). Remember to restart your browser for the changes to take effect. If the problem persists, you should suspect a root cause other than the new SameSite cookie behavior.

If you have turned on third-party cookie blocking (see chrome://settings/cookies), try turning it off. This is particularly relevant for Android WebViews, which block third-party cookies by default, even if they have SameSite=None and Secure.

If you are testing in Incognito Mode, be aware that the default setting for Incognito Mode is to block third-party cookies. This can lead to behavior that appears similar to cross-site cookies being blocked due to lack of a SameSite attribute. This setting can be changed on Incognito Mode's New Tab Page, or in chrome://settings/cookies.

Try clearing your cache and cookies to see if the problem still reproduces.

Check DevTools for issues with SameSite cookies. Unfortunately, Chrome can only tell you when there are cookies that will behave differently under the new SameSite behavior, but it can’t tell you which cookies might be responsible for site breakage. However, if there are no issues about SameSite cookies on any important domains, there may be a different root cause to the problem.

(Note that prior to Chrome 85, there were messages about non-compliant cookies emitted to the JavaScript console in DevTools on each page load. In Chrome 85, these messages were removed from the console. The Issues tab is now the place to look for this information about SameSite cookies, and contains more debugging information than the console messages previously did.)

Using the DevTools Network panel

Open the Network panel in DevTools and capture the network activity that occurs when reproducing the problem. If the expected network activity is absent, reload the page by pressing Ctrl+R in DevTools. Find the request or requests that are not working properly. This may be a request that returns an error code like 403 (indicating an authentication problem, possibly caused by missing cookies), it may be highlighted in red, etc. It may be helpful to check the cookies listed in the Issues tab, as they should link directly to the affected requests (if they do not, refresh the page to ensure that the request is captured on the Network tab). Another helpful way to filter requests is to click on the "Has blocked cookies" checkbox at the rightmost side of the toolbar with the filter box.

Click on the problematic request and go to the Cookies tab (right under the timeline, next to Headers, Preview, Response, Timing, etc.). Click on “show filtered out request cookies”. All the rows highlighted in yellow are cookies that were excluded from the request or rejected from the response for one reason or another. If you hover over the info icon on these blocked cookies, a tooltip will explain why that cookie was excluded. There may be multiple reasons why a cookie was excluded.

Look for cookies that were excluded solely for SameSite reasons. If any of these cookies are important to site functionality, their absence is likely the cause of the problem and they will need to be updated to comply with the new SameSite behavior.

Using Chrome histograms

Chrome records metrics ("histograms") about internal activity as you browse the web. These can help diagnose cookie problems.

Go to chrome://histograms and look for the following entries:

  • Cookie.SameSiteUnspecifiedEffective: This histogram logs the "effective" SameSite mode of every cookie that did not specify a SameSite attribute, i.e. what SameSite rules the browser actually applied to it. The "0" bucket corresponds to None, the "1" bucket corresponds to Lax, and the "3" bucket corresponds to Lax and eligible for Lax+POST.
  • Cookie.SameSiteNoneIsSecure: This histogram logs whether a SameSite=None cookie was Secure. The "0" bucket means not Secure, and the "1" bucket means Secure.

To debug your own site, you can hit "Refresh" at the top of the page to clear the previous histogram entries, then check the histogram entries again after reproducing the problem.

For the full descriptions of every histogram, see histograms.xml and enums.xml (very large files!) in the Chromium source tree.

Using a NetLog dump

Capture a NetLog dump (a record of all network activity) by following these instructions. Make sure to select “Include cookies and credentials” when you capture the log. (Since such a log may contain sensitive information, such as cookies with login information, use your judgement when sharing it with others.) Use the NetLog viewer to open the captured log. 

Click on Events in the sidebar and enter “type:url_request” in the search bar to view all the HTTP(S) requests captured in the log. You can additionally filter by requests with cookies blocked due to SameSite by adding “exclude_samesite” to the search bar.

If you click on each request, you can look for the following things:

  • Any COOKIE_INCLUSION_STATUS entry with status "EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX, WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT" and no other exclusion reasons. This will indicate that the cookie was blocked because of the SameSite-Lax-by-default rules, but would not have been blocked otherwise.

  • Statuses with "WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE". This would indicate that the cookie would be expected to be blocked under Lax-by-default, but is instead allowed due to the 2 minute Lax+POST intervention. Such a cookie may not be causing problems now, but will in the future when Lax+POST is deprecated. See "Testing under Lax+POST" section above for more information.

  • Statuses with "EXCLUDE_SAMESITE_NONE_INSECURE, WARN_SAMESITE_NONE_INSECURE" and no other exclusion reasons. This would indicate that the cookie was blocked because of Cookies-without-SameSite-must-be-Secure, but would not have been blocked otherwise.

  • Statuses indicating EXCLUDE_USER_PREFERENCES mean that third-party cookie blocking is likely enabled, and the blocked cookie was a third-party cookie, or cookies from that site were blocked altogether by the user's settings. You can view cookie settings at chrome://settings/cookies.

Both request and response cookies are shown here. If you suspect that your server’s Set-Cookie response header is incorrect, you can search for “type:cookie_store” and look for a COOKIE_STORE_COOKIE_ADDED entry, which will list the properties of the cookie, as interpreted by Chrome.

To check whether Chrome considers a request cross-site, you can compare the site_for_cookies property of the request (this represents the top-frame origin) with the URL of the request. If these have the same registrable domain or eTLD+1 (the effective Top Level Domain -- something like .com or .net or -- as well as the label immediately to its left) then the request is most likely considered at least Laxly same-site (except in some cases with POST requests) and should attach cookies with SameSite=Lax or cookies defaulted into Lax mode. If they have different registrable domains, or if the site_for_cookies has an empty registrable domain, the request is always considered cross-site. The if the initiator property of the request is either "not an origin" or also shares the same registrable domain as the site_for_cookies and the request URL, then the request should additionally attach Strict cookies.

The NetLog only covers cookies accessed over the network via HTTP(S) and does not include other methods of cookie access such as document.cookie (JavaScript) or chrome.cookies (extensions). For far more information about debugging using NetLogs, refer to this document.

It was working until M86, now it's broken

There is a known bug with Schemeful Same-Site in which the incorrect issue is displayed. Please see Testing and Debugging Tips for Schemeful Same-Site.

This is fixed in M87.