एरर समाधान · डेवलपर एरर

PHP Headers Already Sent: Find the Output and Fix It

Fix PHP's headers already sent warning by finding the file and line where output started: BOM, stray whitespace, echo, or notices. Includes ob_start use.

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

लेखक: SiteDownCheck संपादकीय टीम · अपडेट: अक्टूबर 14, 2026 · 4 मिनट पढ़ने में

The PHP warning Cannot modify header information - headers already sent by appears when your script tries to send an HTTP header after some output has already gone to the browser. HTTP headers must precede the body. Once PHP sends even one byte of body, it must flush the headers first, and after that header(), setcookie(), session_start() and redirects can no longer change them.

The message tells you exactly where to look:

Warning: Cannot modify header information - headers already sent by (output started at /var/www/app/config.php:3) in /var/www/app/login.php on line 27

The part in parentheses is where output began (config.php, line 3). The "in ... on line 27" part is the later line that tried to send a header. The bug is almost always at the first location, not the second. For the WordPress-specific version of this error see WordPress cannot modify header information.

What counts as output

Any of these, before your header call:

  • Whitespace or a blank line before <?php or after a closing ?>
  • A UTF-8 byte order mark (BOM) at the start of a file, saved by some editors
  • echo, print, var_dump, print_r, or inline HTML
  • A PHP notice, warning or deprecation message printed to the page
  • An included file that outputs anything, including a trailing newline after ?>
  • Debug output left in a hook, class or template

Find the real cause

  1. Open the file and line named in "output started at".
  2. If the line is 1, suspect a BOM or whitespace before <?php. Check for a BOM:
head -c 3 config.php | xxd

efbbbf at the start means a BOM. Remove it with an editor option such as "Save with encoding: UTF-8 without BOM", or:

sed -i '1s/^\xEF\xBB\xBF//' config.php
  1. Scan a codebase for files that end with a closing tag followed by blank lines:
grep -rlP '\?>\s*\n+\z' --include=*.php .

The closing ?> tag is optional in files that contain only PHP, and omitting it removes the whole class of trailing-whitespace bugs. PSR-12 requires omitting it in such files.

  1. If the "output" is an error message, the real problem is the notice before it. Fix that, or raise the problem in logs instead of on screen (display_errors = Off).

Fixes

Move header calls before any output

Run session_start(), setcookie(), header() and redirects at the top, before templates or echo. Separate logic from presentation: do the work and the redirect first, then include the view.

<?php
declare(strict_types=1);
session_start();
if (!isset($_SESSION['user'])) {
    header('Location: /login');
    exit;
}

Always call exit after a redirect header so the script does not keep running.

Use output buffering as a safety net

ob_start() at the top of the entry script holds output in memory, so headers can still be sent later:

<?php
ob_start();

Or set it in php.ini:

output_buffering = 4096

This is a mitigation, not a fix. It hides the symptom while the stray output remains, and large buffers use memory. Use it for legacy code you cannot restructure now.

Check included files

Search every file included before the header call, including config, helpers and language files. A single trailing newline in an included file is enough. Binary-safe diffs, or opening the file in an editor that shows invisible characters, help.

Watch for functions that send headers implicitly

session_start() sends cookie headers. header() with a redirect, http_response_code(), setcookie() and setrawcookie() do too. Check with headers_sent($file, $line):

if (headers_sent($file, $line)) {
    error_log("Headers already sent in $file:$line");
}

Check the result from outside

After fixing, confirm redirects and cookies behave. The HTTP Header Checker shows the headers you now send, the रीडायरेक्ट चेकर follows the redirect chain, and the Cookie Checker confirms Set-Cookie flags. Use the HTTP स्टेटस चेकर to make sure the page now returns 302 or 200, not a 500. If a fatal error follows the warning, see fix 500 internal server error.

Prevent it

  • Omit ?> at the end of pure PHP files.
  • Configure your editor for UTF-8 without BOM, LF endings, and a single final newline inside PHP code only.
  • Add a linter step that detects output in config files.
  • Keep display_errors off in production.
  • Test login, logout and checkout flows after deploys, since these send headers and cookies. An अपटाइम मॉनिटर with a keyword check on the login page catches regressions.

अगले कदम

सामान्य प्रश्न

Why does the error point to a different file than the one I edited?

The first location is where output began. The second is where you sent a header. Fix the first.

Is ob_start a good fix?

It is a workable stopgap. Finding and removing the stray output is the proper fix.

Why only on some servers?

Different display_errors and output_buffering settings change whether notices appear and whether output is buffered.

Does the closing PHP tag matter?

In files containing only PHP, leaving it out is recommended because trailing whitespace after it becomes output.

Get notified when this fix updates

Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.

यह पेज सामान्य जानकारी है, जिसे हमारी संपादकीय टीम ने लिखा है और दस्तावेज़ीकरण बदलने पर अपडेट किया जाता है। सर्वर और प्रदाता अलग-अलग होते हैं, इसलिए बदलाव पहले सुरक्षित तरीके से जाँचें। देखें: संपादकीय नीति और अस्वीकरण.