diff --git a/core/includes/form.inc b/core/includes/form.inc
index 49ace44..bf298ad 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -397,6 +397,7 @@ function form_state_defaults() {
     'rebuild' => FALSE,
     'rebuild_info' => array(),
     'redirect' => NULL,
+    'error_redirect' => FALSE,
     // @todo 'args' is usually set, so no other default 'build_info' keys are
     //   appended via += form_state_defaults().
     'build_info' => array(
@@ -915,7 +916,16 @@ function drupal_process_form($form_id, &$form, &$form_state) {
 
       // Set a flag to indicate the the form has been processed and executed.
       $form_state['executed'] = TRUE;
+    }
 
+    /**
+     * Redirects if validation passes or on special case where redirect is
+     * needed even after validation fails.
+     *
+     * @see search_box_form_validate()
+     * @see http://drupal.org/node/1789768
+     */
+    if ($form_state['submitted'] && (!form_get_errors() || $form_state['error_redirect']) && !$form_state['rebuild']) {
       // Redirect the form based on values in $form_state.
       drupal_redirect_form($form_state);
     }
diff --git a/core/modules/search/search.module b/core/modules/search/search.module
index 315ae7a..1af13a9 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -1030,21 +1030,18 @@ function search_box($form, &$form_state, $form_id) {
   );
   $form['actions'] = array('#type' => 'actions');
   $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Search'));
+  $form['#validate'][] = 'search_box_form_validate';
   $form['#submit'][] = 'search_box_form_submit';
 
   return $form;
 }
 
 /**
- * Process a block search form submission.
+ * Validates a block search form submission
+ *
+ * @see search_box_form_submit()
  */
-function search_box_form_submit($form, &$form_state) {
-  // The search form relies on control of the redirect destination for its
-  // functionality, so we override any static destination set in the request.
-  // See http://drupal.org/node/292565.
-  if (isset($_GET['destination'])) {
-    unset($_GET['destination']);
-  }
+function search_box_form_validate($form, &$form_state) {
 
   // Check to see if the form was submitted empty.
   // If it is empty, display an error message.
@@ -1060,6 +1057,7 @@ function search_box_form_submit($form, &$form_state) {
   $info = search_get_default_module_info();
   if ($info) {
     $form_state['redirect'] = 'search/' . $info['path'] . '/' . trim($form_state['values'][$form_id]);
+    $form_state['error_redirect'] = TRUE;
   }
   else {
     form_set_error(NULL, t('Search is currently disabled.'), 'error');
@@ -1067,6 +1065,18 @@ function search_box_form_submit($form, &$form_state) {
 }
 
 /**
+ * Process a block search form submission.
+ */
+function search_box_form_submit($form, &$form_state) {
+  // The search form relies on control of the redirect destination for its
+  // functionality, so we override any static destination set in the request.
+  // See http://drupal.org/node/292565.
+  if (isset($_GET['destination'])) {
+    unset($_GET['destination']);
+  }
+}
+
+/**
  * Performs a search by calling hook_search_execute().
  *
  * @param $keys
