form_alter and #element_validate inside .module file Inside my .module file, I have created a hook for alter register_form and add a password field with a custom field-validation:

function xenforo_form_user_register_form_alter(&amp;$form, \Drupal\Core\Form\FormStateInterface $form_state) {
  $form['password'] = array(
    '#type' =&gt; 'password_confirm',
    '#size' =&gt; 25,
    '#required' =&gt; true,
    '#element_validate' =&gt; array('check_password'),
    );
}
function check_password($element, &amp;$form_state) {
  if ($element['#value'] != 'test') {
    form_error($element, t('Error: TEST'));
  }
}


I use #element_validate, and when I submit my form with a bad value $element['#value'] != 'test', I don't have an error and the registration is completed, why #element_validate don't work here please ?

Thanks.

EDIT:

I have find a solution:

  function xenforo_form_user_register_form_alter(&amp;$form, \Drupal\Core\Form\FormStateInterface $form_state) {
    $form['password'] = array(
      '#type' =&gt; 'password_confirm',
      '#size' =&gt; 25,
      '#required' =&gt; true,
      '#attributes' =&gt; array('autocomplete' =&gt; 'off'),
      //'#element_validate' =&gt; array('check_password'),
      '#process' =&gt; array('processPasswordConfirm'),
    );
  }

  function processPasswordConfirm(&amp;$element, \Drupal\Core\Form\FormStateInterface $form_state, &amp;$complete_form) {
    $element['pass1'] =  array(
      '#type' =&gt; 'password',
      '#title' =&gt; t('Password'),
      '#value' =&gt; empty($element['#value']) ? NULL : $element['#value']['pass1'],
      '#required' =&gt; $element['#required'],
      '#attributes' =&gt; array('class' =&gt; array('password-field')),
    );
    $element['pass2'] =  array(
      '#type' =&gt; 'password',
      '#title' =&gt; t('Confirm password'),
      '#value' =&gt; empty($element['#value']) ? NULL : $element['#value']['pass2'],
      '#required' =&gt; $element['#required'],
      '#attributes' =&gt; array('class' =&gt; array('password-confirm')),
    );
    $element['#element_validate'] = array('check_password');
    $element['#tree'] = TRUE;

    return $element;
  }

  function check_password($element, &amp;$form_state) {
    if ($element['#value'] != 'test') {
      //form_error($element, t('Error: TEST'));
    }
  }


But I have again the error with form_error() and password as displayed as two field without
As per @Clive comment, it's probably because password_confirm isn't a single element, it gets converted into two separate fields in a process callback, and doesn't apply the #element_validate to either of those because it can't reconcile which one you were referring to.