diff --git a/core/lib/Drupal/Core/Form/FormValidator.php b/core/lib/Drupal/Core/Form/FormValidator.php
index ee2da65..a9a3c83 100644
--- a/core/lib/Drupal/Core/Form/FormValidator.php
+++ b/core/lib/Drupal/Core/Form/FormValidator.php
@@ -214,8 +214,12 @@ protected function finalizeValidation(&$form, FormStateInterface &$form_state, $
    *   theming, and hook_form_alter functions.
    */
   protected function doValidateForm(&$elements, FormStateInterface &$form_state, $form_id = NULL) {
-    // Recurse through all children.
-    foreach (Element::children($elements) as $key) {
+    // Recurse through all children, sorting the elements so that the order of
+    // error messages displayed to the user matches the order of elements in
+    // the form. Use a copy of $elements so that it is not modified by the
+    // sorting itself.
+    $elements_copy = $elements;
+    foreach (Element::children($elements_copy, TRUE) as $key) {
       if (isset($elements[$key]) && $elements[$key]) {
         $this->doValidateForm($elements[$key], $form_state);
       }
