Introduction: "You've already sent something to the screen, and I can't"
\nIf you've ever seen a white screen with a frightening message like Warning: Cannot modify header information - headers already sent on your website instead of a beautiful page — you are not alone. This is perhaps one of the most popular errors among beginner (and not only) PHP developers. On Stack Overflow, this question has garnered hundreds of thousands of views, and the amount of incorrect code copies in the world is measured in terabytes.
But the good news is that the "Headers already sent" error is not a curse, but simply a strict reminder from PHP: "Hey, you've already started sending HTML code, and now you're trying to modify HTTP headers. You can't do that!".
\nIn this article, we'll break down why the headers already sent error occurs in PHP, how to find it, and most importantly, how to fix it once and for all. Let's go!
\n\n1. What are HTTP headers and why are they "already sent"?
\nBefore diving into the code, let's understand in simple terms what happens "under the hood". When a PHP script executes, it first sends HTTP headers to the browser. These contain metadata: content type (Content-Type), cookies (Set-Cookie), redirects (Location), response status (200, 404, 301), and so on.
Only after all headers does the script start sending the document body — the actual HTML you see on the page. PHP allows you to modify headers only until the first byte of content has been sent.
\nAs soon as you output anything to the screen (via echo, print, var_dump, or even just a space before <?php), PHP considers the headers already sent. Any attempt to call header(), setcookie(), or session_start() after this results in a fatal error.
1.1. Classic example of the error
\n<?php\necho "Hello, world!";\n// Oops! We've already output something.\nheader("Location: https://example.com");\n// Warning: Cannot modify header information - headers already sent\n?>\nIn this example, echo sends text to the document body. After that, PHP cannot overwrite the headers to perform a redirect. It's logical.
2. Top 5 causes of "Headers already sent"
\nThe error can be caused not only by an explicit echo. Here are the most common scenarios that even experienced developers encounter:
- \n
- Space or blank line before
<?php— the most popular "bug". If there is even a single space in the file before the opening tag, it will be sent to the output. \n - Invisible BOM (Byte Order Mark) characters — the file is saved in UTF-8 with BOM encoding. The first 3 bytes (EF BB BF) are considered output. \n
- Output from included files — there is an extra space after
?>in theconfig.phpfile. \n - Errors and warnings — if PHP outputs a warning (e.g., about using an undefined variable), this is also considered sending content. \n
- Functions
print,printf,var_dumpbefore header() — any output function breaks headers. \n
3. How to find the source of the problem: 3 methods
\nBefore fixing, you need to find where the "extra" output comes from. Use one of these methods.
\n\n3.1. Enable display of all errors
\nAdd this to the beginning of the script (before any output):
\n<?php\nerror_reporting(E_ALL);\nini_set('display_errors', 1);\n?>\nPHP often shows the exact line where the output occurred. Look for a message like Output started at /path/to/file.php:12.
3.2. Use the error_get_last() function
\nYou can catch the last error