Add error message on password protected pages

Here’s a combination of these two great answers (21697 & 71284) to similar questions.

wpse241424_check_post_pass() runs early on the wp hook on single password protected pages. If an invalid password is entered, the INVALID_POST_PASS constant is set for use later in the form, and the password entry error cookie is removed to prevent the error message from being visible each time.

wpse241424_post_password_message() is run right before rendering the password form. It checks for the INVALID_POST_PASS constant that it set earlier when an invalid password is encountered, and adds the error message to the form.

function wpse241424_check_post_pass() {

    if ( ! is_single() || ! post_password_required() ) {
        return;
    }

    if ( isset( $_COOKIE['wp-postpass_' . COOKIEHASH ] ) ) {
        define( 'INVALID_POST_PASS', true );

        // Tell the browser to remove the cookie so the message doesn't show up every time
        setcookie( 'wp-postpass_' . COOKIEHASH, NULL, -1, COOKIEPATH );
    }
}
add_action( 'wp', 'wpse241424_check_post_pass' );


/**
 * Add a message to the password form if an invalid password has been entered.
 *
 * @wp-hook the_password_form
 * @param   string $form
 * @return  string
 */
function wpse241424_post_password_message( $form ) {
    if ( ! defined( 'INVALID_POST_PASS' ) ) {
        return $form;
    }

    // Translate and escape.
    $msg = esc_html__( 'Sorry, your password is wrong.', 'your_text_domain' );

    // We have a cookie, but it doesn’t match the password.
    $msg = "<p class="custom-password-message">$msg</p>";

    return $msg . $form;
}
add_filter( 'the_password_form', 'wpse241424_post_password_message' );