I have written a functionality like super admin can put user accounts on "hold". I have to make sure the user account which put his account on hold unable to login. The problem here is the user is able to login if still his account is on hold. I am using a 'custom user meta' field called 'holdUser' while super admin put a user on hold. While user login I am using the wordpress's wp-login action, how to edit wp-login action so that a user cannot login based on a custom user meta field in wordpress. While user account is put on hold I am updating the 'user meta' like below:

if(isset($_GET['user_id']) && ($_GET['action']=='hold'))
  update_user_meta( $_GET['user_id'], 'holdUser',1 );
  wp_mail($email_to, $subject, $content,$headers);

My Login form has the following code:

<form method="post" action="'.$this->SiteUrl.'wp-login.php">
  <input type="text" id="user_login" name="log">
  <input type="password" name="pwd">
  <button target="" class="submit">Login</button>

My Question here is how to edit 'wp-login.php' hook based on a user_meta field 'holdUser' if its value is 1 then not to login that user.?

Update: I wrote a separate hook if user login fails like below:

add_action( 'wp_login_failed', 'my_front_end_login_fail' );
function my_front_end_login_fail( $username ) {
  $referrer = $_SERVER['HTTP_REFERER'];
  if( !empty($referrer) && !strstr($referrer,'wp-login') && !strstr($referrer,'wp-admin') )
    if ( !strstr($referrer,'/?actiont=failed') )
      wp_redirect( $referrer . '/?actiont=failed&message=authentication-failed' );
      wp_redirect( $referrer );

how can I get that on hold message from 'on_hold_error' hook?

2 Answers 2

function myplugin_authenticate_on_hold($user)
    // username and password are correct
    if ($user instanceof WP_User) {
        $on_hold = get_user_meta($user->ID, 'is_on_hold', true);
        if ($on_hold) {
            return new WP_Error('on_hold_error', 'You are on hold');

    return $user;

add_filter('authenticate', 'myplugin_authenticate_on_hold', 21);

The priority needs to be 21, as wp_authenticate_username_password and wp_authenticate_email_password are priority 20. They return an object of the type WP_User if they could authenticate the user. So if the user is authenticated, check if he is on hold. If he is, show the user an error.

Edit: why aren't you using the default login form?

  • Thanks for the reply. I will try your solution. FUI, I have written a hook called 'authenticate' in functions.php for making user to login with only email. My doubt is that Is there any conflicts happen between these 2 hooks? Nov 29, 2016 at 10:30
  • worked like a charm. but my doubt is that how can I get that 'on_hold_error' message showing up at the Login form. If login fails I wrote a separate hook 'wp_login_failed' In that hook how can I get this message. I am updating my above code, plz check it once. Nov 29, 2016 at 10:46
  • Render them in the login page using login_header(__('Log In'), '', $errors);
    – P1nGu1n
    Nov 29, 2016 at 11:31

Use the wp_authenticate_user filter and return a WP_Error to stop the login.

add_filter( 'wp_authenticate_user', 'my_theme_authenticate_user', 1 );

function my_theme_authenticate_user( $user ) {

    if ( is_wp_error( $user ) ) {
        return $user;

    $on_hold = get_user_meta($user->ID, 'holdUser', true );
    if ( (int)$on_hold == 1) {
        return new WP_Error( 'get lost' );

    return $user;

(put the above in your theme's functions.php)

Also, I think you may need to give your form element name="loginform", in order for WordPress to pick up on it and treat it just like the native WP login form and fire all the same hooks, but not sure on this.

PS: It's recommended to use wp_login_form() to create your custom login form, as you'll get other features such as easy way of specifying a redirect URL. https://codex.wordpress.org/Function_Reference/wp_login_form

  • I edited the line where get_user_meta() is, review and change your code if you've already used what I posted before my edit. Also, you may need to typecast $on_hold
    – Dan.
    Nov 29, 2016 at 8:59
  • First, Thanks for the quick reply. I have tried it I have added that code in themes functions.php file but no luck its not working. I think before adding the filter 'wp_authenticate_user' should we need to remove it with remove_filter? Nov 29, 2016 at 9:54
  • No worries. You shouldn't have to remove other filters already on a hook. Anyways, this one should be processed first as it has a priority of 1. hmmm... I'm thinking my answer may not work if you're not generating your form using wp_login_form(). I'll test it today and come back, but feel free to have a go yourself with wp_login_form()
    – Dan.
    Nov 29, 2016 at 10:01
  • Have you also tried putting name="loginform" in the form element in your custom form?
    – Dan.
    Nov 29, 2016 at 10:03
  • Yeah I tried by putting name="loginform" but still the same response, not working. Nov 29, 2016 at 10:24

Your Answer

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

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