I am working on a site where new users are expected to agree to read our site policy before they can proceed. Once a new user logs in, they are redirected to the policy page. To continue to the read of the site, they need to check an "I agree" box.

My problem is that the users are no longer being directed to the policy page anymore, the redirect fails. This is the error message I am getting:

PHP Warning:  Cannot modify header information - headers already sent by (output started at /var/www/html/wp-includes/class.wp-styles.php:225) in /var/www/html/wp-includes/pluggable.php on line 1226
PHP Stack trace:
PHP   1. {main}() /var/www/html/index.php:0
PHP   2. require() /var/www/html/index.php:17
PHP   3. require_once() /var/www/html/wp-blog-header.php:19
PHP   4. include() /var/www/html/wp-includes/template-loader.php:74
PHP   5. policy_redirect() /var/www/html/wp-content/themes/mytheme/landing-page.php:68
PHP   6. wp_redirect() /var/www/html/wp-content/themes/mytheme/functions.php:691
PHP   7. header() /var/www/html/wp-includes/pluggable.php:1226

I'm not really sure what parts of my code are relevant to post here, I haven't touched class.wp-styles.php or pluggable.php.

Here is the redirect function in functions.php:

function policy_agreement_redirect(){
    $url = get_site_url() . "/policy-agreement/";
    wp_redirect($url); //THIS IS LINE 691 WHERE THINGS BREAK

Every page on my site contains something to redirect users in case they are trying to go to a page but haven't agreed to the policy yet. For example, here's what the relevant part of landing-page.php looks like:

 <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
      <div id="post-<?php the_ID(); ?>">
          <div class="entry-content entry">
              <?php the_content(); ?>
              <?php if ( !is_user_logged_in() ) : ?>
                        $url = get_site_url() . "/login/";
                      <p class="warning">
                          <?php _e('You must be logged in to see the team details.', 'profile'); ?>
                    <?php endif; ?>
                    <?php if( !check_policy_agreement() ): ?>
                      <?php policy_agreement_redirect(); ?>
                <?php else : ?>
                <?php if ( count($error) > 0 ) echo '<p class="error">' . implode("<br />", $error) . '</p>'; ?>
               <!-- THE REST OF THE BLOG -->

Any ideas on what is causing this error and what I should try? Any help is appreciated. Thank you!

  • 1
    you can't redirect after output has started.
    – Milo
    Sep 23, 2018 at 2:21

1 Answer 1


As Milo stated, you can't send header information after PHP has begun sending request response body.

Redirects belong in a function hooked into wp_loaded to ensure they run before the request body is generated.

You need something like the following in your functions.php file:

function hook_wp_loaded_require_login() {
    $uri = ( isset( $_SERVER['REQUEST_URI'] ) )
        ? $_SERVER['REQUEST_URI']
        : null;

    if (
        $uri &&
        $uri !== '/login/' &&
        $uri !== '/policy-agreement/' &&
        ! is_user_logged_in()
    ) {
        $url = get_site_url() . "/login/";
add_action( 'wp_loaded', 'hook_wp_loaded_require_login' );

Note: If you use this approach, users will never see your You must be logged in to see the team details. error message and you'll also need to follow up on that policy_agreement_redirect() call...

  • Hi @Gray I see your point and I tried to implement this, however I am getting an error when trying to display my page - "too many redirects"
    – ellen
    Sep 24, 2018 at 1:51
  • nevermind - I still had another redirect in there messing things up. This works perfectly, thank you
    – ellen
    Sep 24, 2018 at 2:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.