Error: headers already sent

The headers already sent error can pop up in a few different forms including:

Cannot modify header information - headers already sent

Session cookie parameters cannot be changed after headers have already been sent

These errors are triggered when PHP is attempting to do something that must happen before any output has been processed, but some output has already been sent.

In Craft CMS specifically, all of the function calls that are required to run before output are handled as part of the application bootstrap phase, ensuring that by the time any templates are rendered, they've all already been processed.

The most common cause of these errors is therefore accidental output, before Craft's bootstrap phase has completed.

This accidental output normally falls into two categories:

Characters Outside Of PHP Blocks #

Any characters that the PHP interpreter encounters outside of a <?php block are treated as output that should be sent immediately. This includes any white space or new lines at the beginning of any .php files that are part of the application.

Debug Output #

If you have included any var_dump, echo or print_r calls to help with debugging, these will trigger immediate output. We sometimes see these included in Craft's index.php file when developers are debugging environment variables and similar. Removing these should resolve the issue.

How to track down where the output occurred #

If you hit one of these errors, but you don't know where the unexpected output occurred, there's a handy PHP function that can help us find it!

$sent = headers_sent($file, $line);
echo($file . ':' . $line);exit;

This will output the file and line which triggered the first output for the current request. It needs to be placed after the output has started, but before the exception has been thrown.

We find that the simplest method for including it is to track down the file where the exception occurred (you should be able to find it from the Exception's stack trace). Then paste the code into that file, directly above where the exception is triggered.


function startSession() {
  session_start(); // If the exception is being thrown here

// Add the output code in above the triggering line
function startSession() {
  $sent = headers_sent($file, $line);
  echo($file . ':' . $line);exit;
  session_start(); // The exception is being thrown here

Re-run your request and you should see both the name and line number of the file that's causing the problem!