diff --git a/core/lib/Drupal/Core/Form/AjaxFormState.php b/core/lib/Drupal/Core/Form/AjaxFormState.php
new file mode 100644
index 0000000..2dfcab9
--- /dev/null
+++ b/core/lib/Drupal/Core/Form/AjaxFormState.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Form\AjaxFormState.
+ */
+
+namespace Drupal\Core\Form;
+
+/**
+ * Stores information about the ajax state of a form.
+ */
+class AjaxFormState extends FormState implements AjaxFormStateInterface {
+
+  /**
+   * If TRUE, the required fields will not get validated during ajax calls. Defaults to FALSE.
+   *
+   * @var bool
+   */
+  protected $suppressRequiredFieldsValidation = FALSE;
+
+  /**
+   * @inheritdoc
+   */
+  public function enforceRequiredFieldsValidationSuppressing($suppress_required_fields_validation = TRUE) {
+    $this->suppressRequiredFieldsValidation = (bool) $suppress_required_fields_validation;
+    return $this;
+  }
+
+  /**
+   * @inheritdoc
+   */
+  public function isRequiredFieldsValidationSuppressed() {
+    return $this->suppressRequiredFieldsValidation;
+  }
+}
diff --git a/core/lib/Drupal/Core/Form/AjaxFormStateInterface.php b/core/lib/Drupal/Core/Form/AjaxFormStateInterface.php
new file mode 100644
index 0000000..61eebe2
--- /dev/null
+++ b/core/lib/Drupal/Core/Form/AjaxFormStateInterface.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Form\AjaxFormStateInterface.
+ */
+
+namespace Drupal\Core\Form;
+
+
+/**
+ * Provides an interface for an object containing the current ajax state of a form.
+ *
+ * This special AjaxFormStateInterface is used for form processing on Ajax requests.
+ * It provides the ability to suppress validation of required fields on ajax calls.
+ *
+ * @ingroup form_api
+ */
+interface AjaxFormStateInterface extends FormStateInterface {
+
+  /**
+   * Enforces the validation for required fields is suppressed.
+   *
+   * @param bool $prevent_required_fields_validation
+   * @return $this
+   */
+  public function enforceRequiredFieldsValidationSuppressing($prevent_required_fields_validation = TRUE);
+
+  /**
+   * Determines if a validation for required fields should be suppressed.
+   *
+   * @return bool
+   *   TRUE if the validation of required fields should be suppressed, FALSE otherwise
+   */
+  public function isRequiredFieldsValidationSuppressed();
+}
diff --git a/core/lib/Drupal/Core/Form/FormValidator.php b/core/lib/Drupal/Core/Form/FormValidator.php
index ee2da65..ee9990e 100644
--- a/core/lib/Drupal/Core/Form/FormValidator.php
+++ b/core/lib/Drupal/Core/Form/FormValidator.php
@@ -223,63 +223,68 @@ protected function doValidateForm(&$elements, FormStateInterface &$form_state, $
 
     // Validate the current input.
     if (!isset($elements['#validated']) || !$elements['#validated']) {
-      // The following errors are always shown.
-      if (isset($elements['#needs_validation'])) {
-        $this->performRequiredValidation($elements, $form_state);
-      }
+      //The validation of required fields might be suppressed on ajax requests
+      $suppress_required_fields_validation = $elements['#required'] && is_subclass_of($form_state, '\Drupal\Core\Form\AjaxFormStateInterface') && $form_state->isRequiredFieldsValidationSuppressed();
 
-      // Set up the limited validation for errors.
-      $form_state->setLimitValidationErrors($this->determineLimitValidationErrors($form_state));
-
-      // Make sure a value is passed when the field is required.
-      if (isset($elements['#needs_validation']) && $elements['#required']) {
-        // A simple call to empty() will not cut it here as some fields, like
-        // checkboxes, can return a valid value of '0'. Instead, check the
-        // length if it's a string, and the item count if it's an array.
-        // An unchecked checkbox has a #value of integer 0, different than
-        // string '0', which could be a valid value.
-        $is_empty_multiple = (!count($elements['#value']));
-        $is_empty_string = (is_string($elements['#value']) && Unicode::strlen(trim($elements['#value'])) == 0);
-        $is_empty_value = ($elements['#value'] === 0);
-        if ($is_empty_multiple || $is_empty_string || $is_empty_value) {
-          // Flag this element as #required_but_empty to allow #element_validate
-          // handlers to set a custom required error message, but without having
-          // to re-implement the complex logic to figure out whether the field
-          // value is empty.
-          $elements['#required_but_empty'] = TRUE;
+      if (!$suppress_required_fields_validation) {
+        // The following errors are always shown.
+        if (isset($elements['#needs_validation'])) {
+          $this->performRequiredValidation($elements, $form_state);
         }
-      }
 
-      // Call user-defined form level validators.
-      if (isset($form_id)) {
-        $this->executeValidateHandlers($elements, $form_state);
-      }
-      // Call any element-specific validators. These must act on the element
-      // #value data.
-      elseif (isset($elements['#element_validate'])) {
-        foreach ($elements['#element_validate'] as $callback) {
-          $complete_form = &$form_state->getCompleteForm();
-          call_user_func_array($form_state->prepareCallback($callback), array(&$elements, &$form_state, &$complete_form));
+        // Set up the limited validation for errors.
+        $form_state->setLimitValidationErrors($this->determineLimitValidationErrors($form_state));
+
+        // Make sure a value is passed when the field is required.
+        if (isset($elements['#needs_validation']) && $elements['#required']) {
+          // A simple call to empty() will not cut it here as some fields, like
+          // checkboxes, can return a valid value of '0'. Instead, check the
+          // length if it's a string, and the item count if it's an array.
+          // An unchecked checkbox has a #value of integer 0, different than
+          // string '0', which could be a valid value.
+          $is_empty_multiple = (!count($elements['#value']));
+          $is_empty_string = (is_string($elements['#value']) && Unicode::strlen(trim($elements['#value'])) == 0);
+          $is_empty_value = ($elements['#value'] === 0);
+          if ($is_empty_multiple || $is_empty_string || $is_empty_value) {
+            // Flag this element as #required_but_empty to allow #element_validate
+            // handlers to set a custom required error message, but without having
+            // to re-implement the complex logic to figure out whether the field
+            // value is empty.
+            $elements['#required_but_empty'] = TRUE;
+          }
         }
-      }
 
-      // Ensure that a #required form error is thrown, regardless of whether
-      // #element_validate handlers changed any properties. If $is_empty_value
-      // is defined, then above #required validation code ran, so the other
-      // variables are also known to be defined and we can test them again.
-      if (isset($is_empty_value) && ($is_empty_multiple || $is_empty_string || $is_empty_value)) {
-        if (isset($elements['#required_error'])) {
-          $form_state->setError($elements, $elements['#required_error']);
+        // Call user-defined form level validators.
+        if (isset($form_id)) {
+          $this->executeValidateHandlers($elements, $form_state);
         }
-        // A #title is not mandatory for form elements, but without it we cannot
-        // set a form error message. So when a visible title is undesirable,
-        // form constructors are encouraged to set #title anyway, and then set
-        // #title_display to 'invisible'. This improves accessibility.
-        elseif (isset($elements['#title'])) {
-          $form_state->setError($elements, $this->t('!name field is required.', array('!name' => $elements['#title'])));
+        // Call any element-specific validators. These must act on the element
+        // #value data.
+        elseif (isset($elements['#element_validate'])) {
+          foreach ($elements['#element_validate'] as $callback) {
+            $complete_form = &$form_state->getCompleteForm();
+            call_user_func_array($form_state->prepareCallback($callback), array(&$elements, &$form_state, &$complete_form));
+          }
         }
-        else {
-          $form_state->setError($elements);
+
+        // Ensure that a #required form error is thrown, regardless of whether
+        // #element_validate handlers changed any properties. If $is_empty_value
+        // is defined, then above #required validation code ran, so the other
+        // variables are also known to be defined and we can test them again.
+        if (isset($is_empty_value) && ($is_empty_multiple || $is_empty_string || $is_empty_value)) {
+          if (isset($elements['#required_error'])) {
+            $form_state->setError($elements, $elements['#required_error']);
+          }
+          // A #title is not mandatory for form elements, but without it we cannot
+          // set a form error message. So when a visible title is undesirable,
+          // form constructors are encouraged to set #title anyway, and then set
+          // #title_display to 'invisible'. This improves accessibility.
+          elseif (isset($elements['#title'])) {
+            $form_state->setError($elements, $this->t('!name field is required.', array('!name' => $elements['#title'])));
+          }
+          else {
+            $form_state->setError($elements);
+          }
         }
       }
 
diff --git a/core/lib/Drupal/Core/Render/Element/RenderElement.php b/core/lib/Drupal/Core/Render/Element/RenderElement.php
index 0283333..c363365 100644
--- a/core/lib/Drupal/Core/Render/Element/RenderElement.php
+++ b/core/lib/Drupal/Core/Render/Element/RenderElement.php
@@ -243,6 +243,11 @@ public static function preRenderAjaxForm($element) {
         'accepts' => 'application/vnd.drupal-ajax'
       );
 
+      //set query options to enforce suppressing of validation of required fields
+      if (isset($settings['suppress_required_fields_validation']) && $settings['suppress_required_fields_validation'] === TRUE) {
+        $settings['options'] = array_merge_recursive($settings['options'], ['query' => ['suppress_required_fields_validation' => 'suppress_required_fields_validation']]);
+      }
+
       // @todo Legacy support. Remove in Drupal 8.
       if (isset($settings['method']) && $settings['method'] == 'replace') {
         $settings['method'] = 'replaceWith';
diff --git a/core/modules/system/src/Controller/FormAjaxController.php b/core/modules/system/src/Controller/FormAjaxController.php
index 46394fc..ba4b41a 100644
--- a/core/modules/system/src/Controller/FormAjaxController.php
+++ b/core/modules/system/src/Controller/FormAjaxController.php
@@ -9,7 +9,7 @@
 
 use Drupal\Core\Ajax\AjaxResponse;
 use Drupal\Core\Ajax\UpdateBuildIdCommand;
-use Drupal\Core\Form\FormState;
+use Drupal\Core\Form\AjaxFormState;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Drupal\Core\Render\MainContent\MainContentRendererInterface;
 use Drupal\Core\Render\RendererInterface;
@@ -120,6 +120,11 @@ public function content(Request $request) {
     $form_state = $ajaxForm->getFormState();
     $commands = $ajaxForm->getCommands();
 
+    //if set by the ajax call settings, the validation of required fields should be suppressed for this call
+    if ($request->get('suppress_required_fields_validation') == 'suppress_required_fields_validation') {
+      $form_state->enforceRequiredFieldsValidationSuppressing(TRUE);
+    }
+
     $this->formBuilder->processForm($form['#form_id'], $form, $form_state);
 
     // We need to return the part of the form (or some other content) that needs
@@ -129,7 +134,7 @@ public function content(Request $request) {
     // button) that triggered the Ajax request to determine what needs to be
     // rendered.
     $callback = NULL;
-    /** @var $form_state \Drupal\Core\Form\FormStateInterface */
+    /** @var $form_state \Drupal\Core\Form\AjaxFormStateInterface */
     if ($triggering_element = $form_state->getTriggeringElement()) {
       $callback = $triggering_element['#ajax']['callback'];
     }
@@ -173,7 +178,7 @@ public function content(Request $request) {
    * @throws \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface
    */
   protected function getForm(Request $request) {
-    $form_state = new FormState();
+    $form_state = new AjaxFormState();
     $form_build_id = $request->request->get('form_build_id');
 
     // Get the form from the cache.
diff --git a/core/modules/system/src/FileAjaxForm.php b/core/modules/system/src/FileAjaxForm.php
index 1be14b4..a5d8067 100644
--- a/core/modules/system/src/FileAjaxForm.php
+++ b/core/modules/system/src/FileAjaxForm.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\system;
 
-use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Form\AjaxFormStateInterface;
 
 /**
  * Wrapper for Ajax forms data and commands, avoiding a multi-return-value tuple.
@@ -24,9 +24,9 @@ class FileAjaxForm {
   protected $form;
 
   /**
-   * The form state.
+   * The ajax form state.
    *
-   * @var \Drupal\Core\Form\FormStateInterface
+   * @var \Drupal\Core\Form\AjaxFormStateInterface
    */
   protected $formState;
 
@@ -56,8 +56,8 @@ class FileAjaxForm {
    *
    * @param array $form
    *   The form definition.
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The form state.
+   * @param \Drupal\Core\Form\AjaxFormStateInterface $form_state
+   *   The ajax form state.
    * @param \Drupal\Core\Ajax\string|string $form_id
    *   The unique form ID.
    * @param \Drupal\Core\Ajax\string|string $form_build_id
@@ -65,7 +65,7 @@ class FileAjaxForm {
    * @param \Drupal\Core\Ajax\CommandInterface[] $commands
    *   The ajax commands.
    */
-  public function __construct(array $form, FormStateInterface $form_state, $form_id, $form_build_id, array $commands) {
+  public function __construct(array $form, AjaxFormStateInterface $form_state, $form_id, $form_build_id, array $commands) {
     $this->form = $form;
     $this->formState = $form_state;
     $this->formId = $form_id;
@@ -113,7 +113,7 @@ public function getFormId() {
   /**
    * Gets the form state.
    *
-   * @return \Drupal\Core\Form\FormStateInterface
+   * @return \Drupal\Core\Form\AjaxFormStateInterface
    */
   public function getFormState() {
     return $this->formState;
