Common causes
- Whitespace or blank lines before <?php or after a closing ?> tag
- A UTF-8 byte order mark (BOM) at the start of a PHP file
- echo, print, var_dump or HTML output before header() or session_start()
- PHP warnings or notices printed to the page before the redirect
- A plugin or theme file edited in an editor that added a BOM or trailing newline
How to fix it
- Open the 'output started at' file. The first path and line in the message is where output began, not where header() failed. In the example it is config.php line 1, which usually means a BOM or whitespace before <?php.
- Remove whitespace and the closing tag. Make sure <?php is the very first bytes of the file. In files that contain only PHP, delete the final ?> tag so trailing newlines can never be sent.
- Strip the byte order mark. Re-save the file as 'UTF-8 without BOM' in your editor. Check from the shell with head -c 3 file.php | xxd; output starting with efbbbf means a BOM is present.
- Move header logic before output. Call session_start(), setcookie() and header('Location: ...') before any echo or HTML. Follow every redirect with exit; so no further code runs.
- Stop warnings printing to the page. Set display_errors = Off in production and log errors instead with log_errors = On. Then fix the warning that was being printed.
Correct redirect pattern
<?php
// No whitespace or BOM before this line
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: /login.php');
exit;
}
// ... HTML output below
// (omit the closing ?> in PHP-only files) How to stop it happening again
- Configure your editor to save PHP files as UTF-8 without BOM
- Omit the closing ?> tag in files that contain only PHP code
- Keep display_errors off in production
- Handle redirects and sessions at the top of the request, before templates render