diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/FormTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/FormTest.php
index 6563339..33a6b9f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Form/FormTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Form/FormTest.php
@@ -172,13 +172,12 @@ function testRequiredCheckboxesRadio() {
     // The only error messages that should appear are the relevant 'required'
     // messages for each field.
     $expected = array();
-    foreach (array('textfield', 'checkboxes', 'select', 'radios') as $key) {
+    foreach (array('textfield', 'picky_textfield', 'checkboxes', 'select', 'radios') as $key) {
+      // If the field has a #required_error, that should appear.
       if (isset($form[$key]['#required_error'])) {
         $expected[] = $form[$key]['#required_error'];
       }
-      elseif (isset($form[$key]['#form_test_required_error'])) {
-        $expected[] = $form[$key]['#form_test_required_error'];
-      }
+      // Otherwise the default required error message should appear.
       else {
         $expected[] = t('!name field is required.', array('!name' => $form[$key]['#title']));
       }
@@ -205,6 +204,7 @@ function testRequiredCheckboxesRadio() {
 
     // Verify that input elements are still empty.
     $this->assertFieldByName('textfield', '');
+    $this->assertFieldByName('picky_textfield', '');
     $this->assertNoFieldChecked('edit-checkboxes-foo');
     $this->assertNoFieldChecked('edit-checkboxes-bar');
     $this->assertOptionSelected('edit-select', '');
@@ -219,6 +219,7 @@ function testRequiredCheckboxesRadio() {
     // error messages.
     $edit = array(
       'textfield' => $this->randomString(),
+      'picky_textfield' => 'foo',
       'checkboxes[foo]' => TRUE,
       'select' => 'foo',
       'radios' => 'bar',
@@ -226,6 +227,43 @@ function testRequiredCheckboxesRadio() {
     $this->drupalPostForm(NULL, $edit, 'Submit');
     $this->assertNoFieldByXpath('//div[contains(@class, "error")]', FALSE, 'No error message is displayed when all required fields are filled.');
     $this->assertRaw("The form_test_validate_required_form form was submitted successfully.", 'Validation form submitted successfully.');
+
+    // Submit again with an invalid value in the picky text field with custom validation,
+    // and an invalid value in the select field with custom validation plus #required_error.
+    // Verify that each gets its custom validation error message, not an error about being required.
+    $edit = array(
+      'textfield' => $this->randomString(),
+      'picky_textfield' => 'bar', // We want this value to be invalid.
+      'checkboxes[foo]' => TRUE,
+      'select' => 'bar', // We want this value to be invalid.
+      'radios' => 'bar',
+    );
+    $this->drupalPost(NULL, $edit, 'Submit');
+
+    // The error messages that should appear are the picky_textfield and select.
+    $expected = array();
+    $expected[] = 'The value bar is not valid in ' . $form['picky_textfield']['#title'] . '.';
+    $expected[] = 'The value bar is not valid in ' . $form['select']['#title'] . '.';
+
+    // Check the page for error messages.
+    $errors = $this->xpath('//div[contains(@class, "error")]//li');
+    foreach ($errors as $error) {
+      $expected_key = array_search($error[0], $expected);
+      // If the error message is not one of the expected messages, fail.
+      if ($expected_key === FALSE) {
+        $this->fail(format_string("Each error message found was expected: @error", array('@error' => $error[0])));
+      }
+      // Remove the expected message from the list once it is found.
+      else {
+        unset($expected[$expected_key]);
+      }
+    }
+
+
+    // Fail if any expected messages were not found.
+    foreach ($expected as $not_found) {
+      $this->fail(format_string("Found each expected error message: @error", array('@error' => $not_found)));
+    }
   }
 
   /**
diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/ValidationTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/ValidationTest.php
index bda5872..c68fa0c 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Form/ValidationTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Form/ValidationTest.php
@@ -208,38 +208,46 @@ function testCustomRequiredError() {
     $form = $form_state = array();
     $form = form_test_validate_required_form($form, $form_state);
 
-    // Verify that a custom #required error can be set.
+    // Verify that a custom #required_error applies if set.
     $edit = array();
     $this->drupalPostForm('form-test/validate-required', $edit, 'Submit');
 
     foreach (element_children($form) as $key) {
-      if (isset($form[$key]['#required_error'])) {
-        $this->assertNoText(t('!name field is required.', array('!name' => $form[$key]['#title'])));
-        $this->assertText($form[$key]['#required_error']);
+      if (isset($form[$key]['#title']) && isset($form[$key]['#required'])) {
+        // If the required field has a #required_error, that should appear.
+        if (isset($form[$key]['#required_error'])) {
+          $this->assertNoText(t('!name field is required.', array('!name' => $form[$key]['#title'])));
+          $this->assertText($form[$key]['#required_error']);
+        }
+        // Otherwise, the default required error should appear.
+        else {
+          $this->assertText(t('!name field is required.', array('!name' => $form[$key]['#title'])));
+        }
       }
-      elseif (isset($form[$key]['#form_test_required_error'])) {
+      // The non-required fields that have a title should not generate an error.
+      elseif (isset($form[$key]['#title'])) {
         $this->assertNoText(t('!name field is required.', array('!name' => $form[$key]['#title'])));
-        $this->assertText($form[$key]['#form_test_required_error']);
       }
     }
     $this->assertNoText(t('An illegal choice has been detected. Please contact the site administrator.'));
 
-    // Verify that no custom validation error appears with valid values.
+    // Verify that no error appears with valid values.
     $edit = array(
       'textfield' => $this->randomString(),
+      'picky_textfield' => 'baz',
       'checkboxes[foo]' => TRUE,
       'select' => 'foo',
+      'radios' => 'bar',
     );
     $this->drupalPostForm('form-test/validate-required', $edit, 'Submit');
 
+    // No error messages about required fields should appear.
     foreach (element_children($form) as $key) {
-      if (isset($form[$key]['#required_error'])) {
+      if (isset($form[$key]['#title'])) {
         $this->assertNoText(t('!name field is required.', array('!name' => $form[$key]['#title'])));
-        $this->assertNoText($form[$key]['#required_error']);
       }
-      elseif (isset($form[$key]['#form_test_required_error'])) {
-        $this->assertNoText(t('!name field is required.', array('!name' => $form[$key]['#title'])));
-        $this->assertNoText($form[$key]['#form_test_required_error']);
+      if (isset($form[$key]['#required_error'])) {
+        $this->assertNoText($form[$key]['#required_error']);
       }
     }
     $this->assertNoText(t('An illegal choice has been detected. Please contact the site administrator.'));
diff --git a/core/modules/system/tests/modules/form_test/form_test.module b/core/modules/system/tests/modules/form_test/form_test.module
index a932868..4d8aa3d 100644
--- a/core/modules/system/tests/modules/form_test/form_test.module
+++ b/core/modules/system/tests/modules/form_test/form_test.module
@@ -148,12 +148,17 @@ function form_test_validate_required_form($form, &$form_state) {
     '#required' => TRUE,
     '#required_error' => t('Please enter a name.'),
   );
+  $form['picky_textfield'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Picky text field (bar is invalid)',
+    '#required' => TRUE,
+    '#element_validate' => $validate,
+  );
   $form['checkboxes'] = array(
     '#type' => 'checkboxes',
     '#title' => 'Checkboxes',
     '#options' => $options,
     '#required' => TRUE,
-    '#form_test_required_error' => t('Please choose at least one option.'),
     '#element_validate' => $validate,
   );
   $form['select'] = array(
@@ -161,7 +166,7 @@ function form_test_validate_required_form($form, &$form_state) {
     '#title' => 'Select',
     '#options' => $options,
     '#required' => TRUE,
-    '#form_test_required_error' => t('Please select something.'),
+    '#required_error' => t('Please select something.'),
     '#element_validate' => $validate,
   );
   $form['radios'] = array(
@@ -187,12 +192,13 @@ function form_test_validate_required_form($form, &$form_state) {
 }
 
 /**
- * Form element validation handler for 'Name' field in form_test_validate_required_form().
+ * Form element validation handler for fields in form_test_validate_required_form().
+ * This always rejects the value "bar", but accepts any other value.
  */
 function form_test_validate_required_form_element_validate($element, &$form_state) {
-  // Set a custom validation error on the #required element.
-  if (!empty($element['#required_but_empty']) && isset($element['#form_test_required_error'])) {
-    form_error($element, $form_state, $element['#form_test_required_error']);
+  // Set a custom error on the element.
+  if ($element['#value'] == 'bar') {
+    form_error($element, $form_state, 'The value bar is not valid in ' . $element['#title'] . '.');
   }
 }
 
