Skip to main content
Blog|
How-to guides

WordPress “Cookies are blocked due to unexpected output”: how to fix it

|
Mar 26, 2026|9 min read
HOW-TO GUIDESWordPress “Cookies are blockeddue to unexpected output”: howto fix itHOSTNEYhostney.comMarch 26, 2026

You try to log in to WordPress, enter your credentials correctly, and see this message: “Cookies are blocked due to unexpected output. For help, please see this documentation or try the support forums.” The login fails. You re-enter your password, same result. The message points you to documentation but does not tell you what the unexpected output actually is.

This error means that something sent output to the browser before WordPress had a chance to set its authentication cookies. HTTP cookies are transmitted via response headers, and headers must be sent before any body content. If even a single character of output is sent before the headers, PHP cannot set cookies anymore. WordPress detects this and shows the error message.

The “unexpected output” is almost always invisible – a space, a newline, a byte order mark (BOM), or a PHP warning that was printed before the cookie headers. Finding and removing that output fixes the error.

How cookies and headers work#

When a browser requests a page, the server sends a response that consists of headers followed by a body, separated by a blank line:

HTTP/1.1 200 OK
Set-Cookie: wordpress_logged_in_abc=value; path=/; HttpOnly
Content-Type: text/html; charset=UTF-8

<html>...

The Set-Cookie header tells the browser to store a cookie. This header must be in the headers section – before the blank line that separates headers from body. Once PHP starts sending body content (even a single space or newline character), the headers are finalized and no more can be added.

WordPress sets authentication cookies during the login process using PHP’s setcookie() function. If any output was already sent – a stray character in a PHP file, a PHP warning, or whitespace before the opening <?php tag – PHP has already flushed the headers, and setcookie() fails. WordPress catches this failure and displays the “cookies are blocked” message.

The PHP warning that underlies this error is:

Warning: Cannot modify header information - headers already sent by (output started at /path/to/file.php:1)

The “(output started at /path/to/file.php:1)” part tells you exactly which file and line produced the premature output. This is the key to fixing the problem.

Cause 1: Whitespace before opening PHP tag#

The most common cause. A PHP file has a space, newline, or other character before the <?php opening tag. When PHP encounters this character, it sends it to the browser as output, which finalizes the headers.

This happens most often in wp-config.php and functions.php because these are the files that developers and hosting tools edit most frequently. A text editor that adds a newline at the beginning of the file, or a copy-paste operation that introduces invisible whitespace, is enough to trigger the error.

How to confirm

Enable debugging to see where output started:

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);

Check wp-content/debug.log for the “Cannot modify header information” warning. The “output started at” path tells you the exact file and line number.

If the line number is 1, the problem is characters before the <?php tag. If the line number is the last line, the problem is characters after the ?> closing tag.

How to fix

Open the file mentioned in the error via SFTP or SSH and remove any characters before <?php . The opening tag must be the very first thing in the file – no spaces, no blank lines, no invisible characters.

# Check for BOM or whitespace before <?php
hexdump -C wp-config.php | head -3

The first bytes should be 3c 3f 70 68 70 (which is <?php in hex). If you see ef bb bf before that, the file has a UTF-8 BOM (byte order mark) that needs to be removed. If you see 20 (space) or 0a (newline), there is whitespace before the tag.

To fix a BOM, open the file in a text editor that supports encoding selection and save it as “UTF-8 without BOM.” In VS Code, click the encoding indicator in the bottom bar, choose “Save with Encoding,” and select “UTF-8.”

Which files to check

The error message tells you which file caused the output. If it does not, check these files in order (they are loaded earliest in WordPress’s boot sequence):

  1. wp-config.php  – the most common culprit
  2. wp-content/themes/your-theme/functions.php
  3. Any must-use plugins in  wp-content/mu-plugins/
  4. Any recently edited plugin file

Cause 2: Whitespace after closing PHP tag#

PHP files can optionally end with a ?> closing tag. If there are any characters (including a newline) after the closing tag, those characters are sent as output. This is why the WordPress coding standards require omitting the closing ?> tag in PHP files – it prevents exactly this problem.

How to confirm

The “output started at” line number is the last line of the file, and that line is ?> followed by whitespace or a blank line.

How to fix

Remove the ?> closing tag and any content after it. The file should end with PHP code and nothing else. This is the recommended practice for all PHP files in WordPress.

Cause 3: PHP warning or notice before headers#

A PHP warning or deprecation notice output before WordPress sets cookies causes the same problem. The warning text is the “unexpected output.” Common warnings that trigger this:

Deprecated: Function get_magic_quotes_gpc() is deprecated in /path/to/old-plugin/file.php
Warning: Undefined variable $foo in /path/to/plugin/settings.php
Notice: Trying to access array offset on value of type null in /path/to/theme/functions.php

How to confirm

Enable WP_DEBUG_LOG and disable WP_DEBUG_DISPLAY :

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

The critical setting is WP_DEBUG_DISPLAY set to false . When this is true (or when display_errors is On in PHP), PHP warnings are printed to the browser, which counts as output and prevents cookies from being set.

Check wp-content/debug.log for warnings. The warnings themselves are not the problem – the problem is that they are being displayed to the browser instead of only logged.

How to fix

Suppress display while keeping logging. The WP_DEBUG_DISPLAY = false setting writes warnings to the log file without sending them to the browser. This fixes the cookie issue immediately while you work on resolving the underlying warnings.

Fix the warnings. PHP warnings indicate real issues – deprecated functions, undefined variables, incompatible code. Update the plugin or theme that generates the warnings. For deprecated function warnings, the plugin likely needs an update to be compatible with your PHP version. See How to display PHP errors and enable error reporting for a complete guide to PHP error configuration.

Check for plugins that force error display. Some debugging or development plugins call ini_set('display_errors', 1) or error_reporting(E_ALL) regardless of your wp-config.php settings. If you have debugging or development plugins active on a production site, deactivate them.

Cause 4: Plugin or theme outputting content too early#

Some plugins or themes output HTML, JavaScript, or other content during WordPress’s initialization phase, before cookies are set. This can happen when a plugin echoes output in a function hooked to an early action (like init or plugins_loaded ) instead of waiting for the appropriate output hook (like wp_head or wp_footer ).

How to confirm

The “output started at” path points to a specific plugin or theme file, and the line number is not the first or last line (ruling out whitespace/BOM issues). The line in question contains an echo , print , or HTML output statement.

How to fix

This is a bug in the plugin or theme. The developer needs to move the output to an appropriate hook. Check for plugin updates – the bug may be fixed in a newer version.

As a temporary workaround, you can use output buffering to capture premature output. Add this to the top of wp-config.php (immediately after <?php ):

ob_start();

This starts PHP’s output buffer, which captures all output until the buffer is flushed. WordPress can then set cookies before the buffered output is sent. This is a workaround, not a fix – the plugin should be updated.

Cause 5: Extra PHP closing and opening tags#

If a file has multiple PHP blocks with whitespace between them, the whitespace between the blocks is sent as output:

<?php
// some code
?>

<?php
// more code
?>

The blank line between ?> and <?php is HTML output (a newline character). This is technically valid PHP but causes header issues when it occurs in files loaded before cookie setting.

How to fix

Remove the intermediate ?> and <?php tags. Use a single PHP block:

<?php
// some code

// more code

Cause 6: UTF-8 BOM in included files#

The byte order mark problem is not limited to wp-config.php. If any file loaded during WordPress’s early initialization has a BOM, the BOM bytes are sent as output. This includes:

  • wp-config.php
  • wp-settings.php  (if modified)
  • Any must-use plugin ( wp-content/mu-plugins/*.php )
  • functions.php  in the active theme
  • Any file required by the above files

How to confirm

Use a hex editor or command-line tool to check for BOM:

file wp-config.php

If the output says “UTF-8 Unicode (with BOM) text”, the file has a BOM.

To check multiple files at once:

grep -rl $'\xEF\xBB\xBF' wp-content/themes/your-theme/
grep -rl $'\xEF\xBB\xBF' wp-content/mu-plugins/

How to fix

Remove the BOM from each affected file. Using sed :

sed -i '1s/^\xEF\xBB\xBF//' filename.php

Or open the file in an editor that shows encoding and save as UTF-8 without BOM.

Quick diagnostic process#

  1. Enable logging, disable display: define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false);
  2. Try logging in again. The attempt will still fail, but the log now captures the details.
  3. Check the debug log: tail -20 wp-content/debug.log
  4. Look for “Cannot modify header information” – the “output started at” tells you the file and line.
  5. Open that file and fix the issue at the reported line (BOM, whitespace, PHP warning, premature echo).
  6. Clear browser cookies for the domain and try logging in again.

Most cases are resolved in under 5 minutes once you find the “output started at” location. The debug log makes this trivial.

How Hostney handles this#

WP_DEBUG_DISPLAY off by default. On Hostney, display_errors is set to Off at the PHP-FPM pool level. PHP warnings are logged but never sent to the browser. This prevents PHP warnings from interfering with cookie headers, even if a plugin generates deprecation notices or undefined variable warnings.

Per-site error logs. Each site has its own PHP error log at ~/.logs/{your-domain}-php.error.log , making it easy to find the “output started at” information without searching through a shared server log.

Container isolation. Each site’s PHP configuration is independent. One site’s display_errors setting does not affect another site’s cookie behavior.

Summary#

“Cookies are blocked due to unexpected output” means something sent output to the browser before WordPress could set its authentication cookies via HTTP headers. The output is almost always invisible whitespace or a BOM before the <?php tag in wp-config.php, or a PHP warning being displayed instead of logged.

Enable WP_DEBUG_LOG with WP_DEBUG_DISPLAY set to false , check the debug log for “Cannot modify header information – headers already sent by”, and fix the file and line number it points to. The fix is almost always removing whitespace, removing a BOM, or suppressing error display. For a complete reference of WordPress errors and their quick fixes, see How to fix the most common WordPress errors.

Related articles