diff --git a/src/Element/WebformEmailConfirm.php b/src/Element/WebformEmailConfirm.php
index 5c2654d3..627a5f7b 100644
--- a/src/Element/WebformEmailConfirm.php
+++ b/src/Element/WebformEmailConfirm.php
@@ -33,6 +33,7 @@ class WebformEmailConfirm extends FormElement {
       '#pre_render' => [
         [$class, 'preRenderCompositeFormElement'],
       ],
+      '#element_validate' => [[$class, 'validateWebformEmailConfirm']],
       '#theme_wrappers' => ['container'],
       '#required' => FALSE,
     ];
@@ -95,21 +96,14 @@ class WebformEmailConfirm extends FormElement {
     $element['mail_2']['#attributes']['class'][] = 'webform-email-confirm';
     $element['mail_2']['#value'] = empty($element['#value']) ? NULL : $element['#value']['mail_2'];
 
-    // Remove properties that are being applied to the sub elements.
+    // Don't require the main element.
     $element['#required'] = FALSE;
+
+    // Remove properties that are being applied to the sub elements.
     unset($element['#title']);
     unset($element['#description']);
     unset($element['#maxlength']);
-    unset($element['#atributes']);
-
-    // Set validation.
-    if (isset($element['#element_validate'])) {
-      $element['#element_validate'] = array_merge([[get_called_class(), 'validateWebformEmailConfirm']], $element['#element_validate']);
-    }
-    else {
-      $element['#element_validate'] = [[get_called_class(), 'validateWebformEmailConfirm']];
-    }
-
+    unset($element['#attributes']);
     return $element;
   }
 
@@ -151,6 +145,12 @@ class WebformEmailConfirm extends FormElement {
       }
     }
 
+    // Set #title for other validation callbacks.
+    // @see \Drupal\webform\WebformElementBase::validateUnique
+    if (isset($element['mail_1']['#title'])) {
+      $element['#title'] = $element['mail_1']['#title'];
+    }
+
     // Email field must be converted from a two-element array into a single
     // string regardless of validation results.
     $form_state->setValueForElement($element['mail_1'], NULL);
diff --git a/src/Tests/Element/WebformElementEmailTest.php b/src/Tests/Element/WebformElementEmailTest.php
index 95d43ef6..b4c44b60 100644
--- a/src/Tests/Element/WebformElementEmailTest.php
+++ b/src/Tests/Element/WebformElementEmailTest.php
@@ -68,7 +68,7 @@ class WebformElementEmailTest extends WebformTestBase {
     $this->drupalGet('webform/test_element_email');
 
     // Check basic email confirm.
-    $this->assertRaw('<div data-drupal-selector="edit-email-confirm-basic" id="edit-email-confirm-basic" class="js-form-wrapper form-wrapper">');
+    $this->assertRaw('<div id="edit-email-confirm-basic" class="js-form-wrapper form-wrapper">');
     $this->assertRaw('<div class="js-form-item form-item js-form-type-email form-type-email js-form-item-email-confirm-basic-mail-1 form-item-email-confirm-basic-mail-1">');
     $this->assertRaw('<label for="edit-email-confirm-basic-mail-1">Email confirm basic</label>');
     $this->assertRaw('<input data-drupal-selector="edit-email-confirm-basic-mail-1" class="webform-email form-email" type="email" id="edit-email-confirm-basic-mail-1" name="email_confirm_basic[mail_1]" value="" size="60" maxlength="254" />');
@@ -77,7 +77,7 @@ class WebformElementEmailTest extends WebformTestBase {
     $this->assertRaw('<input data-drupal-selector="edit-email-confirm-basic-mail-2" class="webform-email-confirm form-email" type="email" id="edit-email-confirm-basic-mail-2" name="email_confirm_basic[mail_2]" value="" size="60" maxlength="254" />');
 
     // Check advanced email confirm w/ custom label.
-    $this->assertRaw('<div data-drupal-selector="edit-email-confirm-advanced" aria-describedby="edit-email-confirm-advanced--description" id="edit-email-confirm-advanced" class="js-form-wrapper form-wrapper">');
+    $this->assertRaw('<div id="edit-email-confirm-advanced" class="js-form-wrapper form-wrapper">');
     $this->assertRaw('<div class="js-form-item form-item js-form-type-email form-type-email js-form-item-email-confirm-advanced-mail-1 form-item-email-confirm-advanced-mail-1">');
     $this->assertRaw('<label for="edit-email-confirm-advanced-mail-1">Email confirm advanced</label>');
     $this->assertRaw('<input data-drupal-selector="edit-email-confirm-advanced-mail-1" aria-describedby="edit-email-confirm-advanced-mail-1--description" class="webform-email form-email" type="email" id="edit-email-confirm-advanced-mail-1" name="email_confirm_advanced[mail_1]" value="" size="60" maxlength="254" placeholder="Enter email address" />');
diff --git a/src/WebformElementBase.php b/src/WebformElementBase.php
index c6fd223a..d3383aea 100644
--- a/src/WebformElementBase.php
+++ b/src/WebformElementBase.php
@@ -1229,10 +1229,10 @@ class WebformElementBase extends PluginBase implements WebformElementInterface {
     $webform_id = $element['#webform'];
     $sid = $element['#webform_submission'];
     $name = $element['#name'];
-    $value = $element['#value'];
+    $value = NestedArray::getValue($form_state->getValues(), $element['#parents']);
 
     // Skip empty unique fields or arrays (aka #multiple).
-    if ($value === '' || is_array($element['#value'])) {
+    if ($value === '' || is_array($value)) {
       return;
     }
 
@@ -1254,7 +1254,7 @@ class WebformElementBase extends PluginBase implements WebformElementInterface {
       elseif (isset($element['#title'])) {
         $t_args = [
           '%name' => empty($element['#title']) ? $element['#parents'][0] : $element['#title'],
-          '%value' => $element['#value'],
+          '%value' => $value,
         ];
         $form_state->setError($element, t('The value %value has already been submitted once for the %name element. You may have already submitted this webform, or you need to use a different value.', $t_args));
       }
