limit_validation_errors resetting form values in submit handler
#limit_validation_errors prevents values from being passed to the submit handler, since they have not been validated. You can whitelist values by passing the form element key to #limit_validation_errors:

'#limit_validation_errors' =&gt; [
  // format follows the same as in the form state values. Elements
  // that are not #tree will be a string. Nested elements will be
  // an array.
  'element1',
  ['wrapper','element2'],
];


If you want to limit validation, but need all the values in the submit handler, then it's better to not use #limit_validation_errors. Instead, you can wrap any validation in a conditional to check if the 'next' button was clicked:

if ($form_state-&gt;getTriggeringElement() == $form['actions']['next']) {
  // Do form validation here. If the 'back' button was clicked, this
  // validation code will not be clicked. It will only be validated if
  // next has been clicked.
}


Note that if you use #required, validation will still happen even with the above code, since #required is handled separately. In this case, I don't use #required, instead I'll add custom validation to the above code:

if ($form_state-&gt;getTriggeringElement() == $form['actions']['next']) {
  // Do form validation here. If the 'back' button was clicked, this
  // validation code will not be clicked. It will only be validated if
  // next has been clicked.
  if (!strlen($form_state-&gt;getValue('some_element')) {
    $form_state-&gt;setError('some_element', $this-&gt;t('Please fill in a value for some field'));
  }
}