Browser cookies are essential for WordPress websites. They maintain login sessions, enable form submissions, and support key user interactions. When these tiny data packets fail to work properly, you can encounter frustrating errors that will lock you out of admin panels, break contact forms, or create endless redirect loops.

One of the most common cookie-related problems is the ‘cookies are blocked’ error. It often appears unexpectedly, sometimes after a routine change to your site.

This guide provides practical, actionable solutions for fixing the ‘cookies are blocked’ error in WordPress, along with tips for resolving other related cookie issues.

Understanding WordPress cookies and how they work

WordPress relies on cookies for authentication and session management. When you log into the admin dashboard, it sets authentication cookies to verify your identity on subsequent page loads. Without them, WordPress can’t maintain login states or remember user preferences.

Here are common WordPress cookies:

  • wordpress_[hash]. Stores authentication details for the WordPress admin screen.
  • wordpress_logged_in_[hash]. Indicates login status and user identity.
  • wp-settings-{time}-[UID]. Saves personal dashboard preferences.
  • comment_author_[hash]. Remembers commenter information.

Cookie-related errors usually occur when PHP sends output before WordPress sets its headers. This premature output prevents proper cookie transmission and triggers various issues, such as:

  • Login failures with the ‘cookies are blocked’ message.
  • Session timeout errors during form submissions.
  • Redirect loops when accessing the wp-admin page.
  • Comment forms losing user-submitted data.

Understanding this behavior helps identify cookie problems. Most issues stem from timing conflicts where code runs too early before WordPress has a chance to set cookies.

How to troubleshoot the ‘Cookies are blocked due to unexpected output’ error

The error indicates that something is sending data to the browser before WordPress has a chance to set its cookies. Fixing it requires a systematic check to identify the source of this premature output.

You might see this error in the following situations:

  • After you edit theme files or wp-config.php.
  • Following plugin installations or updates.
  • When migrating sites between servers.
  • After modifying PHP configurations.

Let’s walk through common causes and how to fix them.

Check for whitespace in PHP files

Look for blank lines or spaces before the opening <?php tag or after the closing ?> tag in key files, especially in wp-config.php.

There are plenty of ways to do this: Secure File Transfer Protocol (SFTP), WordPress’ own file editor (if you can access it), and more:

A CyberDuck window displaying WordPress core files and directories. The listing shows various PHP files and folders along with file sizes and modification dates.
Accessing WordPress files using SFTP.

Even a single space can trigger this error:

// WRONG (Note the space before opening tag)
 <?php
/** WordPress configuration file */

// CORRECT (No whitespace)
<?php
/** WordPress configuration file */

For the closing tag, it’s typical to omit it entirely for pure PHP files:

// GOOD (No need for a closing tag)
define('WP_DEBUG', true);
/* That's all, stop editing! */
require_once(ABSPATH . 'wp-settings.php');


// PROBLEMATIC (A closing tag with potential trailing whitespace)
define('WP_DEBUG', true);
/* That's all, stop editing! */
require_once(ABSPATH . 'wp-settings.php');
?> 

It’s a simple catch that can solve myriad cookie problems.

Scan for Byte Order Mark (BOM) characters

BOM characters are invisible markers that some text editors add to files, and they can interfere with cookie handling in WordPress. This is a simple encoding issue you can fix with your code editor or command line.

In most editors, you’ll find the file encoding option in the status bar or menu. Make sure the file is saved as UTF-8 without BOM.

A code editor displaying WordPress cookie-related PHP code, with UTF-8 encoding visible in a drop-down menu.
Using a code editor to check file encoding.

You can also detect BOM characters with the command line:

# Check for BOM in PHP files
find . -type f -name '*.php' -exec file {} \; | grep "with BOM"

To fix them, open each flagged file and re-save it with UTF-8 (without BOM) selected.

Identify plugin output issues

A classic way of figuring out any WordPress error is to deactivate all plugins through the WordPress admin screen or rename the plugins folder:

# Rename plugins folder to deactivate all plugins
mv wp-content/plugins wp-content/plugins_backup

If the error disappears, you can reactivate plugins one by one to identify the culprit. Common plugin issues include plugins that echo their output before headers debug messages that display during initialization, and suboptimal plugin activation routines.

Examine theme file implementations

Another typical WordPress error fix is to switch to a default WordPress theme (like Twenty Twenty-Four) to see if the error resolves. If it does, inspect your current theme’s functions.php file for premature output:

// WRONG (Output before headers)
<?php
echo "Debug message"; // This will cause cookie errors
function my_theme_setup() {
    // Theme setup code
}

// CORRECT (No output before headers)
<?php
function my_theme_setup() {
    // Theme setup code
}

// Debug only when appropriate
if (defined('WP_DEBUG') && WP_DEBUG) {
    error_log('Debug message');
}

The simple solution here is to make sure all code is within a function rather than ‘loose’ within the file.

Resolving ‘Cookies are blocked or not supported by your browser’ errors

This version of the cookie error points to browser-side issues rather than server problems. Unlike the ‘unexpected output’ error, this issue requires a different (less technical) troubleshooting approach.

Google Chrome

Chrome’s Privacy and Security settings page showing cookie controls and site exceptions.
The third-party settings option within Google Chrome.

For Google Chrome, go to Settings > Privacy and security > Third-party cookies and:

  1. Click Add next to Sites allowed to use third-party cookies.
  2. Enter your domain (e.g., [*.]yourdomain.com).
  3. Enable Including third-party cookies on this site.

Microsoft Edge

With Microsoft Edge, these options are within the Cookies and site permissions settings page:

Edge’s detailed cookie settings interface with toggles and explanations.
Settings cookies within Microsoft Edge.

Brave

For Brave, you can click on the Shield icon in the address bar, open up the Block third-party cookies drop-down menu, and select the option you wish:

The Kinsta website home page with a Brave privacy popup overlay. The popup shows cookie management options among other privacy settings.
Changing blocking for third-party cookies in Brave.

Firefox

For Firefox, access cookie settings through Settings > Privacy and Security > Cookies and Site Data:

Firefox’s Enhanced Tracking Protection showing Standard level and blocked elements.
Setting cookies within Firefox.

Standard mode is good for balanced privacy and functionality. For specific site exceptions, click the Manage Exceptions button and add your WordPress site’s URL:

Firefox dialog box for managing Enhanced Tracking Protection exceptions.
Adding a site exception within Firefox.

Safari

Safari has an option within its Settings > Advanced screen. This offers a Block all cookies option, which you should uncheck:

Safari’s Advanced preferences with privacy and cookie controls.
Safari’s cookie options.

In short, regardless of the browser you choose, there will be an option within its settings to change how it handles cookies.

Security plugin interference

Your WordPress security plugins can sometimes implement aggressive cookie policies that interfere with your setup. There are three common conflict points to check:

You might already understand if a security plugin is the cause of a ‘cookies are blocked’ error if you temporarily deactivate your plugins. If a security plugin is a potential cause, you can adjust settings rather than disable it. For example:

// Example: Whitelist WordPress admin cookies in a security plugin
add_filter('security_plugin_allowed_cookies', function($cookies) {
    $cookies[] = 'wordpress_logged_in_*';
    $cookies[] = 'wordpress_sec_*';
    $cookies[] = 'wp-settings-*';
    return $cookies;
});

However, the better approach is to contact the plugin’s developer and ascertain whether there’s something they can do. The main point is that you want to keep a security plugin active, as not having one could do more harm than good.

Server configuration impact

Sometimes, server settings can masquerade as browser issues. You can check some server-side configurations to resolve this, such as the PHP session settings in your php.ini file:

session.cookie_secure = On    ; Only for HTTPS sites
session.cookie_httponly = On  ; Prevents JavaScript access
session.cookie_samesite = Lax ; Cross-site request protection

You can also look at web server headers that might affect cookies. For Nginx servers (Kinsta’s choice), look to verify any cookie-related headers:

# Example Nginx configuration
location ~ \.php$ {
    fastcgi_param HTTP_COOKIE $http_cookie;
    fastcgi_pass_header Set-Cookie;
}

If you can’t access your Nginx configuration files and use Kinsta’s WordPress hosting, the Kinsta support team can help. The team can also look at your server-level configs if you suffer from redirect loops.

How to fix WordPress login redirect loops

Redirect loops create a frustrating cycle in which WordPress keeps redirecting between the login page and the admin dashboard without successful user authentication. This typically happens when authentication cookies fail to persist between requests.

WordPress checks for valid authentication cookies after login. If the check fails, it redirects users back to the wp-login.php page.

To resolve this type of issue, enable WordPress debugging and monitor your debug.log file to identify redirect patterns and cookie states during authentication attempts.

Check WordPress URL settings

The most common cause of redirect loops is a difference between the home and site URL within WordPress’ settings:

The WordPress General Settings page showing the Site URL and WordPress Address fields.
The Site URL settings within WordPress.

In short, these need to be an exact match. You can do it through the WordPress backend or change the values in wp-config.php:

define('WP_HOME', 'https://kinsta.com');
define('WP_SITEURL', 'https://kinsta.com');

You should ensure that both values use identical protocols (HTTP versus HTTPS) and domains (with or without www) here. Mixed content warnings can also cause cookie errors, which relate to your SSL settings. Checking and fixing mixed content errors is a breeze.

Define the cookie domain explicitly

When WordPress creates authentication cookies, it needs to know the exact domain scope for those cookies to function properly.

Without explicit configuration, WordPress attempts to determine the ‘cookie domain’ itself, which can fail in complex hosting setups, subdomain installations, or when using non-standard domain configurations.

To resolve the issue, you can add explicit cookie domain settings to wp-config.php:

// For standard domains
define('COOKIE_DOMAIN', 'kinsta.com');

// For subdomains needing parent domain cookies
define('COOKIE_DOMAIN', '.kinsta.com');

// For specific subdirectory installations
define('ADMIN_COOKIE_PATH', '/');
define('COOKIEPATH', '/');
define('SITECOOKIEPATH', '/');

These settings will be critical if WordPress runs in subdirectories, if you manage Multisite networks, or if your site operates across multiple subdomains.

The cookie domain will tell the browser which parts of your site can read and write specific cookies. This will make login persistence and session management more consistent.

How to solve ‘session expired’ errors in WordPress forms

Session expiration errors can be frustrating when you attempt to submit forms, particularly on contact pages, checkout processes, and multi-step forms. These errors occur when WordPress nonces expire or when session cookies fail to maintain a state between form display and submission.

A contact form showing a session expiration error. The form contains a red error message stating Your session has expired. Please refresh the page and try again at the top, followed by input fields for name, email, and a message textarea with placeholder text about services. A blue
A session expired message for a site form.

These tokens expire after a set period — for WordPress, this is typically 24-48 hours — though the actual validity window is shorter for security reasons.

You can optimize your PHP session settings for handling forms through the php.ini file for your server:

; php.ini adjustments
session.gc_maxlifetime = 3600  ; 1 hour
session.cookie_lifetime = 0    ; Until browser closes
session.cache_expire = 180     ; 3 hours

You might also find caching conflicts relating to your forms. Page caching can often cause session errors when serving stale nonces. You can add the following to your theme’s functions.php file:

// Add this to your theme's functions.php file
// Exclude form pages from cache
function exclude_form_pages_from_cache($bypass) {
    // Contact form pages
    if (is_page(array('contact', 'quote-request'))) {
        return true;
    }    

    // WooCommerce checkout
    if (function_exists('is_checkout') && is_checkout()) {
        return true;
    }

    return $bypass;
}
add_filter('kinsta_cache_bypass', 'exclude_form_pages_from_cache');

If you get in touch with Kinsta support, the team can add exclusions to the Nginx cache for you.

Working with specific form functionality

The most effective approach for preventing session expired errors focuses on three proven solutions: cache exclusions, session extension, and plugin-specific configurations.

WooCommerce checkout forms can be susceptible to session issues because they maintain cart data and user information across multiple pages. WooCommerce uses its session management system:

// Add this to your theme's functions.php file
// Extend WooCommerce session length
add_filter('wc_session_expiration', function() {
    return 7 * DAY_IN_SECONDS; // 7 days instead of default 2 days
});

// Ensure WooCommerce pages bypass cache
add_action('init', function() {
    if (function_exists('is_cart') && (is_cart() || is_checkout() || is_account_page())) {
        if (!defined('DONOTCACHEPAGE')) {
            define('DONOTCACHEPAGE', true);
        }
    }
});

Multi-step and AJAX forms often experience session issues due to caching conflicts. A reliable generic approach works across most form plugins:

// Add this to your theme's functions.php file
// Extend WordPress nonce lifetime globally
add_filter('nonce_life', function() {
    return 12 * HOUR_IN_SECONDS; // 12 hours instead of 24 hours for better reliability
});

// Exclude pages with forms from cache by URL pattern
function exclude_form_urls_from_cache($bypass) {
    $request_uri = $_SERVER['REQUEST_URI'];

    // Common form page patterns
    if (strpos($request_uri, '/contact') !== false ||
        strpos($request_uri, '/quote') !== false ||
        strpos($request_uri, '/application') !== false ||
        isset($_POST['action'])) { // Any AJAX form submission
        return true;
    }

    return $bypass;
}
add_filter('kinsta_cache_bypass', 'exclude_form_urls_from_cache');

Gravity Forms provides the most reliable session management among contact form plugins:

// Add this to your theme's functions.php file
// Extend incomplete submission storage time
add_filter('gform_incomplete_submissions_expiration_days', function($days) {
    return 7; // Keep incomplete submissions for 7 days instead of 30
});

// Exclude Gravity Forms AJAX from cache
add_action('init', function() {
    if (isset($_POST['gform_ajax']) || (isset($_GET['page']) && $_GET['page'] === 'gf_entries')) {
        if (!defined('DONOTCACHEPAGE')) {
            define('DONOTCACHEPAGE', true);
        }
    }
});

When it comes to form session management and resolving cookie errors, you might not have a hook or filter to work with. The best approach is to contact the developer directly to ascertain your options.

How to prevent and troubleshoot WordPress cookie errors

One of the most proactive ways to prevent cookie errors on your WordPress website is by following established coding standards. Your primary task is to set cookies before any output reaches the browser. You can do this by checking the header status before setting cookies:

// Always check headers_sent() before setting cookies
if (!headers_sent()) {
    setcookie('custom_cookie', $value, time() + 3600, COOKIEPATH, COOKIE_DOMAIN);
}

You can capture any accidental output before you send headers through buffering. This is invaluable when working with third-party code that might echo content:

// Use output buffering for safety
ob_start();
// Your theme/plugin code that might produce output
ob_end_flush();

Proper hook timing can help you set cookies at the appropriate stage in the WordPress lifecycle. For instance, the init action fires after WordPress loads but before sending headers, which is ideal:

// Proper plugin initialization timing
add_action('init', function() {
    // Cookie operations here, not earlier
    if (!is_admin()) {
        wp_set_auth_cookie($user_id);
    }
});

Your server-level PHP settings can impact cookie behavior. This is where you can further configure your php.ini file to control how PHP handles sessions, set output buffering, and implement cookie security:

; Recommended php.ini settings with explanations
output_buffering = 4096          ; Captures accidental output before headers
session.cookie_secure = On       ; Forces HTTPS-only cookies for security
session.cookie_httponly = On     ; Prevents JavaScript access to cookies
session.cookie_samesite = Lax    ; Protects against CSRF attacks
session.use_strict_mode = On     ; Prevents session fixation attacks

Nginx configuration directly affects how cookies flow between WordPress and visitors’ browsers. Since Kinsta uses Nginx as its web server, this is another area of optimization for cookie-related issues. Essentially, you’ll need to set an ample buffer size so Nginx can process the data before handling headers.

Larger buffer sizes prevent Upstream sent too big header errors that can occur with complex WordPress sites using multiple plugins. When these buffers are too small, Nginx might truncate headers or fail to process cookies properly.

Security headers at the Nginx level also provide an additional layer of protection for all cookies set by your WordPress site.

WordPress debug logging

Debug logging can show you WordPress’s internal operations, but the standard error messages don’t contain enough information for troubleshooting. The debug log can capture the full context:

// Debugging in wp-config.php with strategic logging
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
define('SCRIPT_DEBUG', true);      // Uses non-minified scripts for better debugging
define('SAVEQUERIES', true);        // Tracks database queries that might affect sessions

// Custom cookie logging to trace execution flow
add_action('init', function() {
    if (defined('WP_DEBUG') && WP_DEBUG) {
        error_log('=== Cookie Debug Start ===');
        error_log('Cookie state: ' . print_r($_COOKIE, true));
        error_log('Headers sent: ' . (headers_sent($file, $line) ? "Yes at $file:$line" : 'No'));
        error_log('Request URI: ' . $_SERVER['REQUEST_URI']);
        error_log('=== Cookie Debug End ===');
    }
});

This captures the complete picture of a cookie error. The SCRIPT_DEBUG constant forces WordPress to use non-minified JavaScript and CSS files, which makes it easier to identify interfering scripts. SAVEQUERIES will track all database queries to help you identify database issues relating to the session.

Browser developer tools inspection

Modern browser DevTools can help you debug cookie issues in real time. The Network tab reveals the exact headers being sent and received, while the Application/Storage tab shows current cookie states.

The Kinsta website with browser developer tools open at the bottom. The Network tab shows multiple resource requests including JavaScript files, with details such as file sizes, load times, and HTTP status codes.
The Network Tab within a browser’s DevTools.

Using the console gives you a programmatic way to investigate and manipulate cookies during your troubleshooting:

// Create a detailed cookie report
console.table(document.cookie.split(';').map(c => {
    const [name, value] = c.trim().split('=');
    const decoded = decodeURIComponent(value);
    return {
        name, 
        value: decoded,
        length: value.length,
        encoded: value !== decoded
    };
}));

// Monitor cookie changes in real-time
const cookieObserver = new MutationObserver(() => {
    console.log('Cookie change detected:', new Date().toISOString());
    console.log('New state:', document.cookie);
});

// Watch for any DOM changes that might trigger cookie updates
cookieObserver.observe(document.documentElement, {
    subtree: true, 
    attributes: true,
    characterData: true
});

This will reveal the timing issues that cause cookie errors. For example, the Network tab shows if Set-Cookie headers arrive too late in the response, while the Application tab will display current cookie values, domains, paths, and expiration times.

The MutationObserver approach caches dynamic cookie changes that might occur through JavaScript. This will help you identify client-side code that is interfering with WordPress cookies.

Query Monitor integration

To go beyond WordPress debugging and logging, you can use Query Monitor. For cookie debugging, it reveals when headers are sent and which code triggers premature output:

// Custom Query Monitor collector for comprehensive cookie debugging
class QM_Collector_Cookies extends QM_Collector {
    public $id = 'cookies';

    public function process() {
        // Capture current cookie state
        $this->data['cookies'] = $_COOKIE;

        // Identify where headers were sent
        $this->data['headers_sent'] = headers_sent($file, $line);
        $this->data['output_location'] = $file . ':' . $line;

        // Track output buffer status
        $this->data['ob_level'] = ob_get_level();
        $this->data['ob_status'] = ob_get_status(true);

        // Record WordPress action sequence
        $this->data['current_action'] = current_action();
        $this->data['did_action'] = array(
            'init' => did_action('init'),
            'wp_loaded' => did_action('wp_loaded'),
            'template_redirect' => did_action('template_redirect')
        );
    }
}

// Register collector with Query Monitor
add_filter('qm/collectors', function($collectors) {
    $collectors['cookies'] = new QM_Collector_Cookies();
    return $collectors;
});

This custom collector plugs into Query Monitor and adds a dedicated panel for debugging cookies. It doesn’t just show the state of cookies — it gives you full context around potential issues.

You’ll also see whether output buffering is active and what level it’s at. On top of that, the action sequence pinpoints exactly where in WordPress’s execution flow the problem is happening.

Plugin conflict resolution

Automated testing can catch bugs relating to cookies before they reach production. Unit tests will verify that your code sets cookies correctly and handles edge cases properly.

Systematic plugin testing will show up conflicts without the typical manual deactivation. Automating the approach will save troubleshooting time and give you a definitive answer about which plugins cause cookie issues:

// Automated plugin conflict testing with detailed reporting
function test_plugin_conflicts() {
    $active_plugins = get_option('active_plugins');
    $problematic_plugins = array();

    // Create a testing function specific to your issue
    $test_cookie_function = function() {
        // Clear any existing output
        ob_clean();

        // Attempt to set a test cookie
        if (!headers_sent()) {
            setcookie('test_cookie', 'value', time() + 3600, '/');
            return true;
        }
        return false;
    };

    foreach ($active_plugins as $plugin) {
        // Deactivate single plugin
        deactivate_plugins($plugin);

        // Clear any cached data
        wp_cache_flush();

        // Test cookie functionality
        if ($test_cookie_function()) {
            $problematic_plugins[] = $plugin;
            error_log("Plugin causing cookie issue: " . $plugin);
        }

        // Reactivate plugin
        activate_plugins($plugin);
    }

    // Generate detailed report
    if (!empty($problematic_plugins)) {
        error_log("=== Cookie Conflict Report ===");
        error_log("Problematic plugins: " . implode(', ', $problematic_plugins));
        error_log("Total conflicts found: " . count($problematic_plugins));
    }

    return $problematic_plugins;
}

Here, the code tests each plugin in isolation to prevent false positives from plugin interactions. The cache flush ensures clean testing conditions for each plugin, and the detailed reporting helps you prioritize which plugins to replace or reconfigure.

How Kinsta can help you resolve WordPress cookie errors

Kinsta’s caching system is designed to work with WordPress sites, and by extension, its cookies. Unlike many generic hosts, Kinsta implements intelligent exclusions to avoid issues with login sessions or e-commerce carts. For example:

  • Kinsta’s cache system automatically bypasses caching for logged-in users based on WordPress authentication cookies.
  • Shopping cart cookies from WooCommerce and Easy Digital Downloads are excluded from caching to ensure proper cart behavior.

This means you won’t face the common issue where caching prevents cookies from working properly. The system intelligently serves cached content to anonymous visitors while ensuring logged-in users and customers see personalized, uncached content.

The MyKinsta dashboard gives you some fundamental settings for handling cookies, but the APM Tool can be an asset when resolving cookie errors.

The Kinsta APM Tool interface displaying a transaction sample for wp-cron.php. The table shows a timestamp, duration, and result. Below is a transaction trace timeline showing database queries with their respective durations and percentages.
The Kinsta APM Tool.

You have a few ways to monitor for cookie-related issues here:

  • Uptime checks to detect authentication problems.
  • Error logging that captures cookie-related warnings.
  • Performance metrics that reveal cookie-dependent slowdowns.

If you combine this with Kinsta’s performance optimization, you have a robust environment where cookie errors rarely occur, and when they do, they’re easier to resolve.

Beyond this, Kinsta’s support team can assist with more complex cookie configurations. For example:

  • Setting up custom cache exceptions for specific cookie patterns.
  • Configuring server settings to optimize cookie handling.
  • Troubleshooting edge cases such as Multisite cookie domains.

The team can also recommend plugin solutions compatible with Kinsta’s environment, and steer you away from those solutions not suited to Kinsta’s hosting.

Summary

The ‘cookies are blocked’ error in WordPress will stem from various sources, but most share common solutions. There are some systematic troubleshooting steps you can follow to put things right on your website:

  • Remove whitespace and BOM characters from PHP files.
  • Configure proper browser cookie settings.
  • Address server-side session management.
  • Exclude form pages from caching.
  • Implement proper development practices if necessary.

Kinsta’s managed hosting environment simplifies many of these challenges through intelligent caching, staging environments, and specialized support.

If you want to eliminate cookie errors permanently, Kinsta’s infrastructure can handle cookie management complexities automatically. It also provides tools for custom configurations when you need them.

Jeremy Holcombe Kinsta

Senior Editor at Kinsta, WordPress Web Developer, and Content Writer. Outside of all things WordPress, I enjoy the beach, golf, and movies. I also have tall people problems.