Meet "Headers already sent" — Your New Enemy (and Friend)
\n\nIf you've ever written any PHP, you've likely encountered this error. It appears suddenly, often at the worst possible moment — when you've almost finished your script. The message is scary, red, and it seems like your entire code is broken. But in reality, this is one of the most useful errors in PHP. It teaches you to work correctly with the HTTP protocol.
\n\nIn this tutorial, we'll break down why the Headers already sent error occurs, how to diagnose it, and most importantly, how to fix it once and for all. We won't just copy an answer from Stack Overflow — we'll understand the core concept. Let's go!
What Are HTTP Headers and Why Does PHP Complain About Them?
\n\nBefore we can fix it, we need to understand the anatomy. When PHP sends a response to the browser, it does so in two stages:
\n\n- \n
- First — headers. This is the metadata: content type (
Content-Type), encoding, cookies, response status (200 OK, 404 Not Found). \n - Then — the response body. This is the actual HTML, text, JSON — what the user sees. \n
The problem is that PHP cannot send headers after it has started sending the body. If you try to call header() after you've already output even a single character (even a space), PHP will throw an error:
Warning: Cannot modify header information - headers already sent by (output started at /path/to/file.php:12)\n\nThat's the whole magic. The error is not fatal — it just warns you that your header() didn't work. But the consequences can be serious: a redirect won't happen, a cookie won't be set, a JSON response will break.
\n\nTop 5 Reasons Why This Happens
\n\nLet's break down the most common scenarios. Do any of these sound familiar?
\n\n1. A Space or Blank Line Before <?php
\n\nThis is a classic. You open a file, and before the opening <?php tag, there is a space, a blank line, or a BOM (Byte Order Mark) character. PHP treats this character as part of the output — and off it goes.
// ❌ Error: space before <?php\n <?php\nheader('Location: /new-page.php');\n?>\n\n// ✅ Correct: no characters before <?php\n<?php\nheader('Location: /new-page.php');\n?>\n\n2. Output via echo or print Before header()
\n\nA logical but common beginner mistake: outputting something first, and then trying to redirect the user.
\n\n<?php\necho "Hello, world!";\nheader('Location: /thanks.php'); // ❌ Error: output already occurred\n?>\n\n3. HTML Code Before a PHP Block
\n\nThe file might contain mixed code: HTML markup first, then PHP logic with header().
\n\n<!DOCTYPE html>\n<html>\n<head>\n <title>My Site</title>\n</head>\n<body>\n<?php\nheader('Location: /login.php'); // ❌ Error: HTML already sent\n?>\n</body>\n</html>\n\n4. PHP Errors and Functions Like var_dump()
\n\nThe script might output warnings or debug information before calling header(). For example, if you have display_errors enabled and PHP outputs a warning.
<?php\nvar_dump($some_variable); // Data output\nheader('Content-Type: application/json'); // ❌ Error\n?>\n\n5. Invisible Characters in Included Files (include/require)
\n\nYou include a file using include or require, and at the end of that file, there is an extra blank line or space after the closing ?>.
// config.php\n<?php\n$db_host = 'localhost';\n?>\n // ← This space after ?> breaks everything!\n\nHow to Find the Source of the Problem: Step-by-Step Diagnosis
\n\nThe most important thing — the error always indicates exactly where the output started. Read the message carefully