Make WordPress return 200OKs instead of 503 (Internal Server Error)’s when in maintenance mode

When wordpress goes into “maintenance mode”, i.e. when it is updating itself or plugins/themes, it throws a page to the end user telling them it is updating.

When it goes into this mode, it begins throwing HTTP Status Code 503’s (Internal Server Error).

This is a huge problem for people running wordpress containers behind a load balancer. WordPress isn’t broken. It’s not irrecoverable. It’s doing a job. It’s doing the right thing. ELB’s don’t know this and making them accept 503 as a healthy check is stupid.

So how do you change that to something better? Like a 200 OK (hey everything is FINE. I’m serving valid content, which happens to be a maintenance page.)

Edit the file:

$WORDPRESS_ROOT/wp-includes/load.php

Find the function wp_maintenance:

/**
 * Die with a maintenance message when conditions are met.
 *
 * Checks for a file in the WordPress root directory named ".maintenance".
 * This file will contain the variable $upgrading, set to the time the file
 * was created. If the file was created less than 10 minutes ago, WordPress
 * enters maintenance mode and displays a message.
 *
 * The default message can be replaced by using a drop-in (maintenance.php in
 * the wp-content directory).
 *
 * @since 3.0.0
 * @access private
 *
 * @global int $upgrading the unix timestamp marking when upgrading WordPress began.
 */
function wp_maintenance() {
        if ( ! file_exists( ABSPATH . '.maintenance' ) || wp_installing() ) {
                return;
        }

        global $upgrading;

        include( ABSPATH . '.maintenance' );
        // If the $upgrading timestamp is older than 10 minutes, don't die.
        if ( ( time() - $upgrading ) >= 600 ) {
                return;
        }

        /**
         * Filters whether to enable maintenance mode.
         *
         * This filter runs before it can be used by plugins. It is designed for
         * non-web runtimes. If this filter returns true, maintenance mode will be
         * active and the request will end. If false, the request will be allowed to
         * continue processing even if maintenance mode should be active.
         *
         * @since 4.6.0
         *
         * @param bool $enable_checks Whether to enable maintenance mode. Default true.
         * @param int  $upgrading     The timestamp set in the .maintenance file.
         */
        if ( ! apply_filters( 'enable_maintenance_mode', true, $upgrading ) ) {
                return;
        }

        if ( file_exists( WP_CONTENT_DIR . '/maintenance.php' ) ) {
                require_once( WP_CONTENT_DIR . '/maintenance.php' );
                die();
        }

        require_once( ABSPATH . WPINC . '/functions.php' );
        wp_load_translations_early();

        header( 'Retry-After: 600' );

        wp_die(
                __( 'Briefly unavailable for scheduled maintenance. Check back in a minute.' ),
                __( 'Maintenance' ),
                // !!!!!! CHANGE THIS to 200
                503
        );
}

And change that last 503, to a 200.

Now when your containers are updating, your load balancer won’t kill them. I suspect this will help all sorts of use-cases even for Kubernetes services without having to tell your health checks to tolerate 503s, which are rightfully kept for termination.

Don’t be fooled by Plugins which change maintenance pages. Those plugins throw a “user-land” page, i.e. it’s still on top of wordpress. This maintenance mode is “kernel-land”, i.e. in wordpress itself, not a page on top of wordpress. Seeing that hardcoded constant should tell you there’s no way to intercept it.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.