diff --git a/includes/form.inc b/includes/form.inc
index baadcef..0602d31 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -1345,8 +1345,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);
     }
