diff --git a/core/includes/form.inc b/core/includes/form.inc
index 13e3e83..d8e9440 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -3021,6 +3021,8 @@ function form_process_password_confirm($element) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Validates a password_confirm element.
  */
 function password_confirm_validate($element, &$element_state) {
@@ -3357,6 +3359,8 @@ function form_process_pattern($element, &$form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * #element_validate callback for #pattern form element property.
  *
  * @param $element
@@ -3702,6 +3706,8 @@ function form_process_table($element, &$form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * #element_validate callback for #type 'table'.
  *
  * @param array $element
@@ -3838,6 +3844,8 @@ function form_process_machine_name($element, &$form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Form element validation handler for machine_name elements.
  *
  * Note that #maxlength is validated by _form_validate() already.
@@ -4264,8 +4272,9 @@ function form_pre_render_email($element) {
 }
 
 /**
- * Form element validation handler for #type 'email'.
+ * Implements callback_form_element_validate().
  *
+ * Form element validation handler for #type 'email'.
  * Note that #maxlength and #required is validated by _form_validate() already.
  */
 function form_validate_email(&$element, &$form_state) {
@@ -4335,8 +4344,9 @@ function form_pre_render_range($element) {
 }
 
 /**
- * Form element validation handler for #type 'number'.
+ * Implements callback_form_element_validate().
  *
+ * Form element validation handler for #type 'number'.
  * Note that #required is validated by _form_validate() already.
  */
 function form_validate_number(&$element, &$form_state) {
@@ -4443,8 +4453,9 @@ function form_pre_render_search($element) {
 }
 
 /**
- * Form element validation handler for #type 'url'.
+ * Implements callback_form_element_validate().
  *
+ * Form element validation handler for #type 'url'.
  * Note that #maxlength and #required is validated by _form_validate() already.
  */
 function form_validate_url(&$element, &$form_state) {
@@ -4457,6 +4468,8 @@ function form_validate_url(&$element, &$form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Form element validation handler for #type 'color'.
  */
 function form_validate_color(&$element, &$form_state) {
diff --git a/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/ckeditor/plugin/StylesCombo.php b/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/ckeditor/plugin/StylesCombo.php
index a787676..c3c2b4f 100644
--- a/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/ckeditor/plugin/StylesCombo.php
+++ b/core/modules/ckeditor/lib/Drupal/ckeditor/Plugin/ckeditor/plugin/StylesCombo.php
@@ -90,6 +90,8 @@ public function settingsForm(array $form, array &$form_state, Editor $editor) {
   }
 
   /**
+   * Implements callback_form_element_validate().
+   *
    * #element_validate handler for the "styles" element in settingsForm().
    */
   public function validateStylesValue(array $element, array &$form_state) {
diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module
index 79905f8..f99a72b 100644
--- a/core/modules/datetime/datetime.module
+++ b/core/modules/datetime/datetime.module
@@ -151,6 +151,8 @@ function datetime_field_instance_settings_form($field, $instance) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Validation callback for the datetime widget element.
  *
  * The date has already been validated by the datetime form type validator and
@@ -189,6 +191,8 @@ function datetime_datetime_widget_validate(&$element, &$form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Validation callback for the datelist widget element.
  *
  * The date has already been validated by the datetime form type validator and
@@ -633,6 +637,8 @@ function form_type_datetime_value($element, $input = FALSE) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Validation callback for a datetime element.
  *
  * If the date is valid, the date object created from the user input is set in
@@ -984,6 +990,8 @@ function form_type_datelist_value($element, $input = FALSE, &$form_state = array
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Validation callback for a datelist element.
  *
  * If the date is valid, the date object created from the user input is set in
diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module
index 3c68c46..bd71c8b 100644
--- a/core/modules/entity_reference/entity_reference.module
+++ b/core/modules/entity_reference/entity_reference.module
@@ -350,7 +350,10 @@ function _entity_reference_element_validate_filter(&$element, &$form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Form element validation handler; Stores the new values in the form state.
+ * Stores the new values in the form state.
  *
  * @see entity_reference_field_instance_settings_form()
  */
diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php
index 6a8df6f..1c6c6de 100644
--- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php
+++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php
@@ -90,7 +90,7 @@ public function errorElement(array $element, array $error, array $form, array &$
   }
 
   /**
-   * Validates an element.
+   * Implements callback_form_element_validate().
    */
   public function elementValidate($element, &$form_state, $form) { }
 
diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc
index cde15f4..a01a0f9 100644
--- a/core/modules/field/field.attach.inc
+++ b/core/modules/field/field.attach.inc
@@ -1049,7 +1049,7 @@ function field_attach_validate(EntityInterface $entity, array $options = array()
 }
 
 /**
- * Performs field validation against form-submitted field values.
+ * Implements callback_form_element_validate().
  *
  * There are two levels of validation for fields in forms: widget validation and
  * and field validation.
diff --git a/core/modules/field/tests/modules/field_test/field_test.field.inc b/core/modules/field/tests/modules/field_test/field_test.field.inc
index d2f4a94..0e65487 100644
--- a/core/modules/field/tests/modules/field_test/field_test.field.inc
+++ b/core/modules/field/tests/modules/field_test/field_test.field.inc
@@ -176,6 +176,8 @@ function field_test_field_instance_settings_form($field, $instance) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Form element validation handler for 'test_field_widget_multiple' widget.
  */
 function field_test_widget_multiple_validate($element, &$form_state) {
diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc
index de03e50..2dbdba8 100644
--- a/core/modules/file/file.field.inc
+++ b/core/modules/file/file.field.inc
@@ -129,6 +129,8 @@ function file_field_instance_settings_form($field, $instance) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Render API callback: Validates the maximum upload size field.
  *
  * Ensures that a size has been entered and that it can be parsed by
@@ -144,6 +146,8 @@ function _file_generic_settings_max_filesize($element, &$form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Render API callback: Validates the allowed file extensions field.
  *
  * This function is assigned as an #element_validate callback in
@@ -168,6 +172,8 @@ function _file_generic_settings_extensions($element, &$form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Render API callback: Validates the file destination field.
  *
  * Removes slashes from the beginning and end of the destination value and
@@ -398,9 +404,10 @@ function file_field_widget_value($element, $input = FALSE, $form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Validation callback for upload element on file widget. Checks if user has
  * uploaded more files than allowed.
- *
  * This validator is used only when cardinality not set to 1 or unlimited.
  */
 function file_field_widget_multiple_count_validate($element, &$form_state, $form) {
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index c31ab28..f0e2eb1 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -1078,6 +1078,8 @@ function file_managed_file_value(&$element, $input = FALSE, $form_state = NULL)
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Render API callback: Validates the managed_file element.
  *
  * This function is assigned as a #element_validate callback in
diff --git a/core/modules/image/image.admin.inc b/core/modules/image/image.admin.inc
index 9ed3aa9..1e5ca54 100644
--- a/core/modules/image/image.admin.inc
+++ b/core/modules/image/image.admin.inc
@@ -346,6 +346,8 @@ function image_effect_form_submit($form, &$form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Element validate handler to ensure a hexadecimal color value.
  */
 function image_effect_color_validate($element, &$form_state) {
@@ -358,6 +360,8 @@ function image_effect_color_validate($element, &$form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Element validate handler to ensure that either a height or a width is
  * specified.
  */
diff --git a/core/modules/image/image.field.inc b/core/modules/image/image.field.inc
index a287620..973211d 100644
--- a/core/modules/image/image.field.inc
+++ b/core/modules/image/image.field.inc
@@ -205,6 +205,8 @@ function image_field_instance_settings_form($field, $instance) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Element validate function for resolution fields.
  */
 function _image_field_resolution_validate($element, &$form_state) {
@@ -391,8 +393,9 @@ function image_field_widget_process($element, &$form_state, $form) {
 }
 
 /**
- * Validate callback for alt and title field, if the user wants them required.
+ * Implements callback_form_element_validate().
  *
+ * Validate callback for alt and title field, if the user wants them required.
  * This is separated in a validate function instead of a #required flag to avoid
  * being validated on the process callback.
  */
diff --git a/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php b/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php
index 8a1aebb..3356da9 100644
--- a/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php
+++ b/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php
@@ -107,8 +107,9 @@ public function settingsForm(array $form, array &$form_state) {
   }
 
   /**
-   * Form element validation handler for link_field_widget_form().
+   * Implements callback_form_element_validate().
    *
+   * Form element validation handler for link_field_widget_form().
    * Conditionally requires the link title if a URL value was filled in.
    */
   function validateTitle(&$element, &$form_state, $form) {
diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php
index 40f24df..fc62e25 100644
--- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php
+++ b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php
@@ -65,7 +65,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr
   }
 
   /**
-   * Form validation handler for widget elements.
+   * Implements callback_form_element_validate().
    *
    * @param array $element
    *   The form element.
diff --git a/core/modules/options/options.module b/core/modules/options/options.module
index 1062f7f..d659240 100644
--- a/core/modules/options/options.module
+++ b/core/modules/options/options.module
@@ -175,6 +175,8 @@ function options_field_settings_form($field, $instance, $has_data) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Element validate callback; check that the entered values are valid.
  */
 function options_field_settings_form_validate_allowed_values($element, &$form_state) {
diff --git a/core/modules/path/path.module b/core/modules/path/path.module
index 03be41b..a7cdb8a 100644
--- a/core/modules/path/path.module
+++ b/core/modules/path/path.module
@@ -144,6 +144,8 @@ function path_form_node_form_alter(&$form, $form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Form element validation handler for URL alias form element.
  *
  * @see path_form_node_form_alter()
diff --git a/core/modules/rest/lib/Drupal/rest/Plugin/views/row/DataFieldRow.php b/core/modules/rest/lib/Drupal/rest/Plugin/views/row/DataFieldRow.php
index 756f9a4..6420227 100644
--- a/core/modules/rest/lib/Drupal/rest/Plugin/views/row/DataFieldRow.php
+++ b/core/modules/rest/lib/Drupal/rest/Plugin/views/row/DataFieldRow.php
@@ -108,6 +108,8 @@ public function buildOptionsForm(&$form, &$form_state) {
   }
 
   /**
+   * Implements callback_form_element_validate().
+   *
    * Form element validation handler for \Drupal\rest\Plugin\views\row\DataFieldRow::buildOptionsForm().
    */
   public function validateAliasName($element, &$form_state) {
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 9d6922c..4300dbb 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -3600,6 +3600,39 @@ function hook_filetransfer_info_alter(&$filetransfer_info) {
  */
 
 /**
+ * @addtogroup callbacks
+ * @{
+ */
+
+  /**
+   * Validate a form element during form submission.
+   *
+   * Callback for drupal_get_form().
+   *
+   *  @param array $element
+   *   An associative array containing the properties and children of the
+   *   table element.
+   * @param array $form_state
+   *   The current state of the form.
+   *
+   * @ingroup callbacks
+   *
+   */
+  function callback_form_element_validate($element, $form_state) {
+    if (!is_array($element['#value']) || !count(array_filter($element['#value']))) {
+      form_error($element, t('No items selected.'));
+    }
+    elseif (!isset($element['#value']) || $element['#value'] === '') {
+      form_error($element, t('No item selected.'));
+    }
+  }
+
+/**
+ * @} End of "addtogroup callbacks".
+ */
+
+
+/**
  * @defgroup update_api Update versions of API functions
  * @{
  * Functions that are similar to normal API functions, but do not invoke hooks.
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 c7a85a3..01f9e1d 100644
--- a/core/modules/system/tests/modules/form_test/form_test.module
+++ b/core/modules/system/tests/modules/form_test/form_test.module
@@ -454,6 +454,8 @@ function form_test_validate_form($form, &$form_state) {
 
 /**
  * Form validation handler for form_test_validate_form().
+ *
+ * Form element validation handler for the 'test' element.
  */
 function form_test_validate_form_validate(&$form, &$form_state) {
   if ($form_state['values']['name'] == 'validate') {
@@ -621,7 +623,7 @@ function form_test_limit_validation_errors_form($form, &$form_state) {
 }
 
 /**
- * Form element validation handler for the 'test' element.
+ * Implements callback_form_element_validate().
  */
 function form_test_limit_validation_errors_element_validate_test(&$element, &$form_state) {
   if ($element['#value'] == 'invalid') {
@@ -926,8 +928,9 @@ function form_test_storage_form($form, &$form_state) {
 }
 
 /**
- * Form element validation handler for 'value' element in form_test_storage_form().
+ * Implements callback_form_element_validate().
  *
+ * Form element validation handler for 'value' element in form_test_storage_form().
  * Tests updating of cached form storage during validation.
  */
 function form_test_storage_element_validate_value_cached($element, &$form_state) {
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index 0e8d921..f22d6ce 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -1119,6 +1119,8 @@ function taxonomy_term_title(Term $term) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Form element validate handler for taxonomy term autocomplete element.
  */
 function taxonomy_autocomplete_validate($element, &$form_state) {
diff --git a/core/modules/translation/translation.module b/core/modules/translation/translation.module
index f62832d..37f8659 100644
--- a/core/modules/translation/translation.module
+++ b/core/modules/translation/translation.module
@@ -169,8 +169,9 @@ function translation_form_node_type_form_alter(&$form, &$form_state) {
 }
 
 /**
- * Checks if translation can be enabled.
+ * Implements callback_form_element_validate().
  *
+ * Checks if translation can be enabled.
  * If language is set to one of the special languages
  * and language selector is not hidden, translation cannot be enabled.
  */
diff --git a/core/modules/translation_entity/translation_entity.module b/core/modules/translation_entity/translation_entity.module
index 7f9bf97..d3e8343 100644
--- a/core/modules/translation_entity/translation_entity.module
+++ b/core/modules/translation_entity/translation_entity.module
@@ -935,8 +935,9 @@ function translation_entity_language_configuration_element_process(array $elemen
 }
 
 /**
- * Form validation handler for element added with translation_entity_language_configuration_element_process().
+ * Implements callback_form_element_validate().
  *
+ * Form validation handler for element added with translation_entity_language_configuration_element_process().
  * Checks whether translation can be enabled: if language is set to one of the
  * special languages and language selector is not hidden, translation cannot be
  * enabled.
diff --git a/core/modules/views/lib/Drupal/views/Plugin/entity_reference/selection/ViewsSelection.php b/core/modules/views/lib/Drupal/views/Plugin/entity_reference/selection/ViewsSelection.php
index c3cf1ac..0d20eec 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/entity_reference/selection/ViewsSelection.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/entity_reference/selection/ViewsSelection.php
@@ -197,6 +197,8 @@ public function validateAutocompleteInput($input, &$element, &$form_state, $form
   public function entityQueryAlter(SelectInterface $query) {}
 
   /**
+   * Implements callback_form_element_validate().
+   *
    * Element validate; Check View is valid.
    */
   public function settingsFormValidate($element, &$form_state, $form) {
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index 23d2651..a7024ac 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -1719,6 +1719,8 @@ function views_process_check_options($element, &$form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Validation callback for query tags.
  */
 function views_element_validate_tags($element, &$form_state) {
diff --git a/core/modules/views_ui/admin.inc b/core/modules/views_ui/admin.inc
index a723854..8351552 100644
--- a/core/modules/views_ui/admin.inc
+++ b/core/modules/views_ui/admin.inc
@@ -206,6 +206,8 @@ function views_ui_nojs_submit($form, &$form_state) {
 }
 
 /**
+ * Implements callback_form_element_validate().
+ *
  * Form element validation handler for a taxonomy autocomplete field.
  *
  * This allows a taxonomy autocomplete field to be validated outside the
