diff --git a/core/lib/Drupal/Core/Field/WidgetBase.php b/core/lib/Drupal/Core/Field/WidgetBase.php
index b1579f2445..123e5929dc 100644
--- a/core/lib/Drupal/Core/Field/WidgetBase.php
+++ b/core/lib/Drupal/Core/Field/WidgetBase.php
@@ -145,15 +145,15 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f
     $parents = $form['#parents'];
 
     // Determine the number of widgets to display.
+    $field_state = static::getWidgetState($parents, $field_name, $form_state);
+    $max = $field_state['items_count'];
     switch ($cardinality) {
       case FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED:
-        $field_state = static::getWidgetState($parents, $field_name, $form_state);
-        $max = $field_state['items_count'];
         $is_multiple = TRUE;
         break;
 
       default:
-        $max = $cardinality - 1;
+        $max = min($max, $cardinality - 1);
         $is_multiple = ($cardinality > 1);
         break;
     }
@@ -221,7 +221,8 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f
       ];
 
       // Add 'add more' button, if not working with a programmed form.
-      if ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && !$form_state->isProgrammed()) {
+      $is_unlimited = $cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED;
+      if (($is_unlimited || $max < $cardinality - 1) && !$form_state->isProgrammed()) {
         $id_prefix = implode('-', array_merge($parents, [$field_name]));
         $wrapper_id = Html::getUniqueId($id_prefix . '-add-more-wrapper');
         $elements['#prefix'] = '<div id="' . $wrapper_id . '">';
@@ -293,14 +294,15 @@ public static function addMoreAjax(array $form, FormStateInterface $form_state)
 
     // Go one level up in the form, to the widgets container.
     $element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -1));
+    $cardinality = $element['#cardinality'];
+    $delta = $element['#max_delta'];
 
     // Ensure the widget allows adding additional items.
-    if ($element['#cardinality'] != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
+    if ($cardinality != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && $delta > $cardinality - 1) {
       return;
     }
 
     // Add a DIV around the delta receiving the Ajax effect.
-    $delta = $element['#max_delta'];
     $element[$delta]['#prefix'] = '<div class="ajax-new-content">' . (isset($element[$delta]['#prefix']) ? $element[$delta]['#prefix'] : '');
     $element[$delta]['#suffix'] = (isset($element[$delta]['#suffix']) ? $element[$delta]['#suffix'] : '') . '</div>';
 
