diff --git a/core/includes/form.inc b/core/includes/form.inc
index 226d4a6..c3b9e64 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -1308,8 +1308,12 @@ function _form_validate(&$elements, &$form_state, $form_id = NULL) {
   // Also used in the installer, pre-database setup.
   $t = get_t();
 
-  // 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]) {
       _form_validate($elements[$key], $form_state);
     }
