Getting “Cannot modify header information – headers already sent” error on wp-admin only whenever any plugin is activated

Error Diagnosis:

The first Error:

PHP Warning:  An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>. (WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.) in /Applications/MAMP/htdocs/site-url.com/wp-includes/update.php on line 306

This is basically WordPress trying to connect to api.wordpress.org for checking core, plugins, themes or translation related updates. Even if you disable automatic update, WordPress will do these checks because update check is needed for manual updates as well.

The second Error:

PHP Warning:  Cannot modify header information - headers already sent by (output started at /Applications/MAMP/htdocs/site-url.com/wp-includes/update.php:306) in /Applications/MAMP/htdocs/site-url.com/wp-includes/pluggable.php on line 1167

This is most likely the result of the first error (or some other error) that is being sent to the output before WordPress could generate HTTP headers. In fact, if you output anything (with print, echo etc.) before sending HTTP headers, you’ll get this headers already sent error.

Other Errors:

The only other error I’ve seen in your debug.log dump is some plugins using deprecated WordPress function calls. If those plugins have an updated version, these errors will not persist after the update, so they are not really serious.

A better Error management:

When you debug, it’s better to send these errors only to the debug.log file and disable displaying errors to the browser using the following in wp-config.php:

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

When the above is set, instead of printing out the errors to the output buffer (i.e. browser), WordPress will print the errors only in the debug.log file located in your wp-content directory (if it is writable by the web server). The benefit of this is:

  1. It’s easier to check errors (errors, warnings, notices etc.) in the debug.log file than in the browser.

  2. Error output to the browser breaks the site’s html.

  3. By logging error only to the debug.log file, you’ll also avoid the connected headers already sent error all together.

Stop WordPress update check:

Even after you adopt the above debugging method, WordPress will keep generating the first error in your debug.log file. That’s annoying as it’ll fill up debug.log file very fast & you really don’t need to continuously check for updates when you are developing in localhost (especially when you are offline).

Fortunately, you can stop this update check using pre_http_request filter hook. Use the following CODE in your theme’s functions.php file or even better, in a custom plugin and use it to stop WordPress update checks when you are offline or developing in localhost:

add_filter( 'pre_http_request', 'wp_update_check_short_circuit', 20, 3 );
function wp_update_check_short_circuit( $preempt = false, $args, $url ) {
    if ( stripos( $url, 'https://') === 0 ) {
        $url = substr( $url, 8 );
    }
    else {
        $url = substr( $url, 7 );
    }

    // stop other URL(s) requests as well (if you need to) in the same manner
    if ( stripos( $url, 'api.wordpress.org') === 0 ) {
        // WP is trying to get some info, short circuit it with a dummy response
        return array(
            'headers'   => null,
            'body'      => '',
            'response'  => array(
                'code'      => 503,
                'message'   => 'SERVICE_UNAVAILABLE'
                ),
            'cookies'   => array(),
            'filename'  => ''
            );
    }
    // returning false will let the normal procedure continue
    return false;
}

After this, WordPress will no longer generate any update check related errors, as this CODE basically short circuits HTTP request sent to api.wordpress.org using WordPress HTTP API. If you need to short circuit other internal HTTP requests as well, simply modify the above CODE to do so.

Note: Remember to turn off this CODE when you upload your changes to the live server. To make sure you don’t accidentally stop the update check in the live server, it’s better to use the above CODE in a custom plugin. That way you can just enable the plugin only when you are developing in localhost.

Leave a Comment