How to fix "Headers already sent" error in PHP?

Nadia S.

The Problem

How can I fix a “headers already sent” error in PHP?

The Solution

The HTTP header is sent to the web server with the first output, no matter what that is. The header cannot be modified or resent afterward.

If your script attempts to change the HTTP header following any output, you will receive a “headers already sent” error message.

The solution to this error is to restructure your script so that no output is sent before an HTTP-modifying function like header() or setcookie() is called. If you can’t restructure your code or want a quick solution, you can use the ob_start() and ob_end_flush() functions to delay the output until after the HTTP header is modified.

Find the First Output in Your Script

The “headers already sent” error message includes information to help you locate the premature output in your script.

Take a look at this example error message:

Click to Copy
Warning: Cannot modify header information - headers already sent by (output started at /home/Example/index.php:3) in /home/Example/index.php on line 9

The error message tells us the premature output is located in our index.php file on line 3, before the header() function is called on line 9.

If we examine the file, we see an echo statement on line 3 that sends output before the header() function is called on line 9:

Click to Copy
// line 3 echo 'Hello, World!'; // line 9 header("Location: https://example.com");

In this case, we can restructure our code so that our echo statement does not appear before the header is called.

Functions that are similar to echo and would cause the same error include print, print_r, var-dump, imagepng, and imagejpg.

Whitespace or HTML Tags

If the error message flags the first line of your script, a whitespace or HTML tag is likely responsible for the initial output. Remove the whitespace to resolve the issue.

For example:

Click to Copy
// change this <?php // to this <?php

Any HTML code outside of the <?php and ?> tags is sent as output. For example, a <!DOCTYPE html> tag appearing before a call to modify the HTTP header will cause a “headers already sent” error.

Here we have the <!DOCTYPE html> tag before we call the setcookie() function, which modifies the header:

Click to Copy
<!DOCTYPE html> <?php setcookie("lang_cookie", "cookie_data"); ?> <html> <head> <title>My Page</title> </head> <body> <p>My Paragraph</p> </body> </html>

To fix this, place the setcookie() call before <!DOCTYPE html> tag:

Click to Copy
<?php setcookie("lang_cookie", "cookie_data"); ?> <!DOCTYPE html> <html> <head> <title>My Page</title> </head> <body> <p>My Paragraph</p> </body> </html>

Other Possible Sources of Output

If you haven’t located the source of the output yet, have a look at the following:

  • The UTF-8 BOM (Byte-Order-Mark) is an invisible character that will count as output. Find the encoding information of the script in your IDE or text editor. You can change the settings of your text editor to save files as UTF-8 (no BOM) in the future.

  • Error reporting and warnings can sometimes be counted as output and trigger the “headers already sent” error. Check and modify the error display settings of your php.ini or .htaccess file.

  • If you include a file that has any output (including whitespace) before making changes to the HTTP header, you will get the “headers already sent” error.

The ob_start() and ob_end_flush() Buffering Functions

An alternative to restructuring your code is to buffer output using the ob_start() and ob_end_flush() functions so that no output is sent before an attempt to modify the header is made.

Here we use ob_start() after the <?php opening tag and ob_end_flush() before the closing ?> php tag to delay the output until after a call to modify the HTTP header is made:

Click to Copy
<?php ob_start(); echo "Hello, World!"; setcookie("langcookie", "cookiedata"); ob_end_flush(); ?>

Note that you may not be able to view the output of your script in the browser when you use this approach, but it will prevent the “headers already sent” error from being thrown.

Loved by over 4 million developers and more than 90,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.

Share on Twitter
Bookmark this page
Ask a questionJoin the discussion

Related Answers

A better experience for your users. An easier life for your developers.

    TwitterGitHubDribbbleLinkedinDiscord
© 2024 • Sentry is a registered Trademark
of Functional Software, Inc.