Title: wpmu_validate_user_signup
Published: April 25, 2014
Last modified: April 28, 2025

---

# wpmu_validate_user_signup( string $user_name, string $user_email ): array

## In this article

 * [Description](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#description)
 * [Parameters](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#source)
 * [Hooks](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#hooks)
 * [Related](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#wp--skip-link--target)

Sanitizes and validates data required for a user sign-up.

## 󠀁[Description](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#description)󠁿

Verifies the validity and uniqueness of user names and user email addresses, and
checks email addresses against allowed and disallowed domains provided by administrators.

The [‘wpmu_validate_user_signup’](https://developer.wordpress.org/reference/hooks/wpmu_validate_user_signup/)
hook provides an easy way to modify the sign-up process. The value $result, which
is passed to the hook, contains both the user-provided info and the error messages
created by the function. [‘wpmu_validate_user_signup’](https://developer.wordpress.org/reference/hooks/wpmu_validate_user_signup/)
allows you to process the data in any way you’d like, and unset the relevant errors
if necessary.

## 󠀁[Parameters](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#parameters)󠁿

 `$user_name`stringrequired

The login name provided by the user.

`$user_email`stringrequired

The email provided by the user.

## 󠀁[Return](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#return)󠁿

 array The array of user name, email, and the error messages.

 * `user_name` string
 * Sanitized and unique username.
 * `orig_username` string
 * Original username.
 * `user_email` string
 * User email address.
 * `errors` [WP_Error](https://developer.wordpress.org/reference/classes/wp_error/)
 * [WP_Error](https://developer.wordpress.org/reference/classes/wp_error/) object
   containing any errors found.

## 󠀁[Source](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#source)󠁿

    ```php
    function wpmu_validate_user_signup( $user_name, $user_email ) {
    	global $wpdb;

    	$errors = new WP_Error();

    	$orig_username = $user_name;
    	$user_name     = preg_replace( '/\s+/', '', sanitize_user( $user_name, true ) );

    	if ( $user_name !== $orig_username || preg_match( '/[^a-z0-9]/', $user_name ) ) {
    		$errors->add( 'user_name', __( 'Usernames can only contain lowercase letters (a-z) and numbers.' ) );
    		$user_name = $orig_username;
    	}

    	$user_email = sanitize_email( $user_email );

    	if ( empty( $user_name ) ) {
    		$errors->add( 'user_name', __( 'Please enter a username.' ) );
    	}

    	$illegal_names = get_site_option( 'illegal_names' );

    	if ( ! is_array( $illegal_names ) ) {
    		$illegal_names = array( 'www', 'web', 'root', 'admin', 'main', 'invite', 'administrator' );
    		add_site_option( 'illegal_names', $illegal_names );
    	}

    	if ( in_array( $user_name, $illegal_names, true ) ) {
    		$errors->add( 'user_name', __( 'Sorry, that username is not allowed.' ) );
    	}

    	/** This filter is documented in wp-includes/user.php */
    	$illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );

    	if ( in_array( strtolower( $user_name ), array_map( 'strtolower', $illegal_logins ), true ) ) {
    		$errors->add( 'user_name', __( 'Sorry, that username is not allowed.' ) );
    	}

    	if ( ! is_email( $user_email ) ) {
    		$errors->add( 'user_email', __( 'Please enter a valid email address.' ) );
    	} elseif ( is_email_address_unsafe( $user_email ) ) {
    		$errors->add( 'user_email', __( 'You cannot use that email address to signup. There are problems with them blocking some emails from WordPress. Please use another email provider.' ) );
    	}

    	if ( strlen( $user_name ) < 4 ) {
    		$errors->add( 'user_name', __( 'Username must be at least 4 characters.' ) );
    	}

    	if ( strlen( $user_name ) > 60 ) {
    		$errors->add( 'user_name', __( 'Username may not be longer than 60 characters.' ) );
    	}

    	// All numeric?
    	if ( preg_match( '/^[0-9]*$/', $user_name ) ) {
    		$errors->add( 'user_name', __( 'Sorry, usernames must have letters too!' ) );
    	}

    	$limited_email_domains = get_site_option( 'limited_email_domains' );

    	if ( is_array( $limited_email_domains ) && ! empty( $limited_email_domains ) ) {
    		$limited_email_domains = array_map( 'strtolower', $limited_email_domains );
    		$email_domain          = strtolower( substr( $user_email, 1 + strpos( $user_email, '@' ) ) );

    		if ( ! in_array( $email_domain, $limited_email_domains, true ) ) {
    			$errors->add( 'user_email', __( 'Sorry, that email address is not allowed!' ) );
    		}
    	}

    	// Check if the username has been used already.
    	if ( username_exists( $user_name ) ) {
    		$errors->add( 'user_name', __( 'Sorry, that username already exists!' ) );
    	}

    	// Check if the email address has been used already.
    	if ( email_exists( $user_email ) ) {
    		$errors->add(
    			'user_email',
    			sprintf(
    				/* translators: %s: Link to the login page. */
    				__( '<strong>Error:</strong> This email address is already registered. <a href="%s">Log in</a> with this address or choose another one.' ),
    				wp_login_url()
    			)
    		);
    	}

    	// Has someone already signed up for this username?
    	$signup = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->signups WHERE user_login = %s", $user_name ) );
    	if ( $signup instanceof stdClass ) {
    		$registered_at = mysql2date( 'U', $signup->registered );
    		$now           = time();
    		$diff          = $now - $registered_at;
    		// If registered more than two days ago, cancel registration and let this signup go through.
    		if ( $diff > 2 * DAY_IN_SECONDS ) {
    			$wpdb->delete( $wpdb->signups, array( 'user_login' => $user_name ) );
    		} else {
    			$errors->add( 'user_name', __( 'That username is currently reserved but may be available in a couple of days.' ) );
    		}
    	}

    	$signup = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->signups WHERE user_email = %s", $user_email ) );
    	if ( $signup instanceof stdClass ) {
    		$diff = time() - mysql2date( 'U', $signup->registered );
    		// If registered more than two days ago, cancel registration and let this signup go through.
    		if ( $diff > 2 * DAY_IN_SECONDS ) {
    			$wpdb->delete( $wpdb->signups, array( 'user_email' => $user_email ) );
    		} else {
    			$errors->add( 'user_email', __( 'That email address is pending activation and is not available for new registration. If you made a previous attempt with this email address, please check your inbox for an activation email. If left unconfirmed, it will become available in a couple of days.' ) );
    		}
    	}

    	$result = array(
    		'user_name'     => $user_name,
    		'orig_username' => $orig_username,
    		'user_email'    => $user_email,
    		'errors'        => $errors,
    	);

    	/**
    	 * Filters the validated user registration details.
    	 *
    	 * This does not allow you to override the username or email of the user during
    	 * registration. The values are solely used for validation and error handling.
    	 *
    	 * @since MU (3.0.0)
    	 *
    	 * @param array $result {
    	 *     The array of user name, email, and the error messages.
    	 *
    	 *     @type string   $user_name     Sanitized and unique username.
    	 *     @type string   $orig_username Original username.
    	 *     @type string   $user_email    User email address.
    	 *     @type WP_Error $errors        WP_Error object containing any errors found.
    	 * }
    	 */
    	return apply_filters( 'wpmu_validate_user_signup', $result );
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/ms-functions.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/6.9.4/src/wp-includes/ms-functions.php#L468)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-includes/ms-functions.php#L468-L602)

## 󠀁[Hooks](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#hooks)󠁿

 [apply_filters( ‘illegal_user_logins’, array $usernames )](https://developer.wordpress.org/reference/hooks/illegal_user_logins/)

Filters the list of disallowed usernames.

 [apply_filters( ‘wpmu_validate_user_signup’, array $result )](https://developer.wordpress.org/reference/hooks/wpmu_validate_user_signup/)

Filters the validated user registration details.

## 󠀁[Related](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#related)󠁿

| Uses | Description | 
| [sanitize_email()](https://developer.wordpress.org/reference/functions/sanitize_email/)`wp-includes/formatting.php` |

Strips out all characters that are not allowable in an email.

  | 
| [is_email()](https://developer.wordpress.org/reference/functions/is_email/)`wp-includes/formatting.php` |

Verifies that an email is valid.

  | 
| [sanitize_user()](https://developer.wordpress.org/reference/functions/sanitize_user/)`wp-includes/formatting.php` |

Sanitizes a username, stripping out unsafe characters.

  | 
| [wp_login_url()](https://developer.wordpress.org/reference/functions/wp_login_url/)`wp-includes/general-template.php` |

Retrieves the login URL.

  | 
| [mysql2date()](https://developer.wordpress.org/reference/functions/mysql2date/)`wp-includes/functions.php` |

Converts given MySQL date string into a different format.

  | 
| [add_site_option()](https://developer.wordpress.org/reference/functions/add_site_option/)`wp-includes/option.php` |

Adds a new option for the current network.

  | 
| [username_exists()](https://developer.wordpress.org/reference/functions/username_exists/)`wp-includes/user.php` |

Determines whether the given username exists.

  | 
| [email_exists()](https://developer.wordpress.org/reference/functions/email_exists/)`wp-includes/user.php` |

Determines whether the given email exists.

  | 
| [is_email_address_unsafe()](https://developer.wordpress.org/reference/functions/is_email_address_unsafe/)`wp-includes/ms-functions.php` |

Checks an email address against a list of banned domains.

  | 
| [wpdb::get_row()](https://developer.wordpress.org/reference/classes/wpdb/get_row/)`wp-includes/class-wpdb.php` |

Retrieves one row from the database.

  | 
| [wpdb::delete()](https://developer.wordpress.org/reference/classes/wpdb/delete/)`wp-includes/class-wpdb.php` |

Deletes a row in the table.

  | 
| [__()](https://developer.wordpress.org/reference/functions/__/)`wp-includes/l10n.php` |

Retrieves the translation of $text.

  | 
| [apply_filters()](https://developer.wordpress.org/reference/functions/apply_filters/)`wp-includes/plugin.php` |

Calls the callback functions that have been added to a filter hook.

  | 
| [get_site_option()](https://developer.wordpress.org/reference/functions/get_site_option/)`wp-includes/option.php` |

Retrieve an option value for the current network based on name of option.

  | 
| [wpdb::prepare()](https://developer.wordpress.org/reference/classes/wpdb/prepare/)`wp-includes/class-wpdb.php` |

Prepares a SQL query for safe execution.

  | 
| [WP_Error::__construct()](https://developer.wordpress.org/reference/classes/wp_error/__construct/)`wp-includes/class-wp-error.php` |

Initializes the error.

  |

[Show 11 more](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#)

| Used by | Description | 
| [WP_REST_Users_Controller::create_item()](https://developer.wordpress.org/reference/classes/wp_rest_users_controller/create_item/)`wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php` |

Creates a single user.

  | 
| [validate_user_form()](https://developer.wordpress.org/reference/functions/validate_user_form/)`wp-signup.php` |

Validates user sign-up name and email.

  | 
| [validate_blog_signup()](https://developer.wordpress.org/reference/functions/validate_blog_signup/)`wp-signup.php` |

Validates new site signup.

  |

## 󠀁[Changelog](https://developer.wordpress.org/reference/functions/wpmu_validate_user_signup/?output_format=md#changelog)󠁿

| Version | Description | 
| [MU (3.0.0)](https://developer.wordpress.org/reference/since/mu.3.0.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwpmu_validate_user_signup%2F)
before being able to contribute a note or feedback.