Warning: Cannot modify header information - headers already sent by (output started at /path/file.php:12) appears when PHP tries to send a header (redirect, cookie, session) after page content has already been sent. Redirects and logins then fail. The warning itself tells you exactly where the stray output is.
Before you start
- Copy the full warning: the important part is output started at file:line, not the file where the header call failed.
- File Manager or SSH access and a code editor that can show invisible characters.
Read the warning correctly
The message names two places:
- output started at
A.php:12: where something was printed too early. This is what you fix. - in
B.phpon line 80: where the header/redirect was attempted. Usually innocent.
Common causes and fixes
Whitespace before <?php or after ?>
A blank line or space before the opening tag, or after a closing ?> at the end of a file, is sent as output. Open the file named in the warning and:
- Delete anything before
<?phpon line 1. - Remove the closing
?>at the end of pure-PHP files entirely. It is optional, and omitting it prevents this problem.
In WordPress the usual suspects are wp-config.php and a theme's functions.php after manual edits.
UTF-8 BOM
Some editors (notably older Windows tools) save a hidden byte order mark at the start of the file, which counts as output. Check from SSH:
head -c 3 file.php | xxdIf it shows efbb bf, remove it:
sed -i '1s/^\xEF\xBB\xBF//' file.phpOr re-save as "UTF-8 without BOM" in your editor.
echo, print or HTML before a redirect
Code that prints debug output, or HTML outside PHP tags, before calling header('Location: ...') or session_start(). Move the header logic before any output, and always exit; after a redirect.
PHP notices printed to the page
With display_errors on, a notice or deprecation message is itself output and triggers this warning afterwards. Fix the first warning in the log and turn display_errors off on production.
Plugins and themes
If the file is inside a plugin or theme, update it or temporarily disable it, and report the issue to its developer.
About output buffering
Setting output_buffering = 4096 in php.ini hides the symptom by holding output until headers are sent. It can be a short-term workaround, but finding the stray output is the real fix.
Check the fix
Reload the page; logins and redirects should work, and the warning should no longer appear in the error log.
Troubleshooting
- Line 1 named, but nothing visible: a BOM or a space before
<?php. - Warning after a PHP upgrade: new deprecation notices are printed as output; fix them or hide display of errors.
- Only on one server: different
output_bufferingordisplay_errorssettings mask it elsewhere.
Headers already sent FAQ
Why does it work locally but not on the server?
Local setups often enable output buffering, which hides the problem.
Should I remove all closing ?> tags?
In files that contain only PHP, yes. Keep them in templates that mix PHP and HTML.
Does this affect SEO?
Indirectly: failed redirects and broken pages do. Fix it promptly.
