diff --git a/core/lib/Drupal/Core/Field/FieldConfigInterface.php b/core/lib/Drupal/Core/Field/FieldConfigInterface.php
index 11da0df..79486d8 100644
--- a/core/lib/Drupal/Core/Field/FieldConfigInterface.php
+++ b/core/lib/Drupal/Core/Field/FieldConfigInterface.php
@@ -178,7 +178,7 @@ public function addPropertyConstraints($name, array $constraints);
    * @code
    *   // Add a constraint to the 'field_username' FieldItemList.
    *   // e.g. $node->field_username
-   *   $fields['field_username']->addConstraint('UserNameUnique', []);
+   *   $fields['field_username']->addConstraint('UniqueField');
    * @endcode
    *
    * If you wish to apply a constraint to a \Drupal\Core\Field\FieldItem instead
diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UniqueFieldConstraint.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UniqueFieldConstraint.php
new file mode 100644
index 0000000..9c7389b
--- /dev/null
+++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UniqueFieldConstraint.php
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldConstraint.
+ */
+
+namespace Drupal\Core\Validation\Plugin\Validation\Constraint;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Checks if an entity field has a unique value.
+ *
+ * @Constraint(
+ *   id = "UniqueField",
+ *   label = @Translation("Unique field constraint", context = "Validation"),
+ * )
+ */
+class UniqueFieldConstraint extends Constraint {
+
+  public $message = 'A @entity_type with @field_name %value already exists.';
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validatedBy() {
+    return '\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator';
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UniqueFieldValueValidator.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UniqueFieldValueValidator.php
index d6c3910..1917c5c 100644
--- a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UniqueFieldValueValidator.php
+++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UniqueFieldValueValidator.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Validation\Plugin\Validation\Constraint;
 
+use Drupal\Component\Utility\Unicode;
 use Symfony\Component\Validator\Constraint;
 use Symfony\Component\Validator\ConstraintValidator;
 
@@ -37,7 +38,11 @@ public function validate($items, Constraint $constraint) {
       ->execute();
 
     if ($value_taken) {
-      $this->context->addViolation($constraint->message, array("%value" => $item->value));
+      $this->context->addViolation($constraint->message, [
+        '%value' => $item->value,
+        '@entity_type' => $entity->getEntityType()->getLowercaseLabel(),
+        '@field_name' => Unicode::strtolower($items->getFieldDefinition()->getLabel()),
+      ]);
     }
   }
 }
diff --git a/core/modules/aggregator/src/Entity/Feed.php b/core/modules/aggregator/src/Entity/Feed.php
index a5ed081..68effd4 100644
--- a/core/modules/aggregator/src/Entity/Feed.php
+++ b/core/modules/aggregator/src/Entity/Feed.php
@@ -151,7 +151,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
         'weight' => -5,
       ))
       ->setDisplayConfigurable('form', TRUE)
-      ->addConstraint('FeedTitle', []);
+      ->addConstraint('FeedTitle');
 
     $fields['langcode'] = BaseFieldDefinition::create('language')
       ->setLabel(t('Language code'))
@@ -173,7 +173,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
         'weight' => -3,
       ))
       ->setDisplayConfigurable('form', TRUE)
-      ->addConstraint('FeedUrl', []);
+      ->addConstraint('FeedUrl');
 
     $intervals = array(900, 1800, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 604800, 1209600, 2419200);
     $period = array_map(array(\Drupal::service('date.formatter'), 'formatInterval'), array_combine($intervals, $intervals));
diff --git a/core/modules/aggregator/src/Plugin/Validation/Constraint/FeedTitleConstraint.php b/core/modules/aggregator/src/Plugin/Validation/Constraint/FeedTitleConstraint.php
index a8e71a2..a553305 100644
--- a/core/modules/aggregator/src/Plugin/Validation/Constraint/FeedTitleConstraint.php
+++ b/core/modules/aggregator/src/Plugin/Validation/Constraint/FeedTitleConstraint.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\aggregator\Plugin\Validation\Constraint;
 
-use Symfony\Component\Validator\Constraint;
+use Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldConstraint;
 
 /**
  * Supports validating feed titles.
@@ -17,15 +17,8 @@
  *   label = @Translation("Feed title", context = "Validation")
  * )
  */
-class FeedTitleConstraint extends Constraint {
+class FeedTitleConstraint extends UniqueFieldConstraint {
 
   public $message = 'A feed named %value already exists. Enter a unique title.';
 
-  /**
-   * {@inheritdoc}
-   */
-  public function validatedBy() {
-    return '\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator';
-  }
-
 }
diff --git a/core/modules/aggregator/src/Plugin/Validation/Constraint/FeedUrlConstraint.php b/core/modules/aggregator/src/Plugin/Validation/Constraint/FeedUrlConstraint.php
index cf41dee..998b10c 100644
--- a/core/modules/aggregator/src/Plugin/Validation/Constraint/FeedUrlConstraint.php
+++ b/core/modules/aggregator/src/Plugin/Validation/Constraint/FeedUrlConstraint.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\aggregator\Plugin\Validation\Constraint;
 
-use Symfony\Component\Validator\Constraint;
+use Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldConstraint;
 
 /**
  * Supports validating feed URLs.
@@ -17,15 +17,8 @@
  *   label = @Translation("Feed URL", context = "Validation")
  * )
  */
-class FeedUrlConstraint extends Constraint {
+class FeedUrlConstraint extends UniqueFieldConstraint {
 
   public $message = 'A feed with this URL %value already exists. Enter a unique URL.';
 
-  /**
-   * {@inheritdoc}
-   */
-  public function validatedBy() {
-    return '\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator';
-  }
-
 }
diff --git a/core/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php
index e05923d..b7d449b 100644
--- a/core/modules/block_content/src/Entity/BlockContent.php
+++ b/core/modules/block_content/src/Entity/BlockContent.php
@@ -177,7 +177,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setDisplayOptions('form', array(
         'type' => 'language_select',
         'weight' => 2,
-      ));
+      ))
+      ->addConstraint('UniqueField');
 
     $fields['info'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Block description'))
diff --git a/core/modules/block_content/src/Tests/BlockContentCreationTest.php b/core/modules/block_content/src/Tests/BlockContentCreationTest.php
index 6bf250c..9d49a2a 100644
--- a/core/modules/block_content/src/Tests/BlockContentCreationTest.php
+++ b/core/modules/block_content/src/Tests/BlockContentCreationTest.php
@@ -66,8 +66,8 @@ public function testBlockContentCreation() {
     $this->drupalPostForm('block/add/basic', $edit, t('Save'));
 
     // Check that the Basic block has been created.
-    $this->assertRaw(format_string('A block with description %name already exists.', array(
-      '%name' => $edit['info[0][value]']
+    $this->assertRaw(format_string('A custom block with block description %value already exists.', array(
+      '%value' => $edit['info[0][value]']
     )));
     $this->assertResponse(200);
   }
@@ -124,8 +124,8 @@ public function testBlockContentCreationMultipleViewModes() {
     $this->drupalPostForm('block/add/basic', $edit, t('Save'));
 
     // Check that the Basic block has been created.
-    $this->assertRaw(format_string('A block with description %name already exists.', array(
-      '%name' => $edit['info[0][value]']
+    $this->assertRaw(format_string('A custom block with block description %value already exists.', array(
+      '%value' => $edit['info[0][value]']
     )));
     $this->assertResponse(200);
   }
diff --git a/core/modules/block_content/src/Tests/BlockContentTestBase.php b/core/modules/block_content/src/Tests/BlockContentTestBase.php
index 82139c0..9cff6c0 100644
--- a/core/modules/block_content/src/Tests/BlockContentTestBase.php
+++ b/core/modules/block_content/src/Tests/BlockContentTestBase.php
@@ -70,17 +70,20 @@ protected function setUp() {
    *   Defaults to FALSE.
    * @param string $bundle
    *   (optional) Bundle name. Defaults to 'basic'.
+   * @param bool $save
+   *   (optional) Whether to save the block. Defaults to TRUE.
    *
    * @return \Drupal\block_content\Entity\BlockContent
    *   Created custom block.
    */
-  protected function createBlockContent($title = FALSE, $bundle = 'basic') {
+  protected function createBlockContent($title = FALSE, $bundle = 'basic', $save = TRUE) {
     $title = ($title ? : $this->randomMachineName());
-    if ($block_content = entity_create('block_content', array(
+    $block_content = entity_create('block_content', array(
       'info' => $title,
       'type' => $bundle,
       'langcode' => 'en'
-    ))) {
+    ));
+    if ($block_content && $save === TRUE) {
       $block_content->save();
     }
     return $block_content;
diff --git a/core/modules/user/src/Plugin/Validation/Constraint/UserMailUnique.php b/core/modules/user/src/Plugin/Validation/Constraint/UserMailUnique.php
index 210e00c..e275f82 100644
--- a/core/modules/user/src/Plugin/Validation/Constraint/UserMailUnique.php
+++ b/core/modules/user/src/Plugin/Validation/Constraint/UserMailUnique.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\user\Plugin\Validation\Constraint;
 
-use Symfony\Component\Validator\Constraint;
+use Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldConstraint;
 
 /**
  * Checks if a user's email address is unique on the site.
@@ -17,14 +17,8 @@
  *   label = @Translation("User email unique", context = "Validation")
  * )
  */
-class UserMailUnique extends Constraint {
+class UserMailUnique extends UniqueFieldConstraint {
 
   public $message = 'The email address %value is already taken.';
 
-  /**
-   * {@inheritdoc}
-   */
-  public function validatedBy() {
-    return '\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator';
-  }
 }
diff --git a/core/modules/user/src/Plugin/Validation/Constraint/UserNameUnique.php b/core/modules/user/src/Plugin/Validation/Constraint/UserNameUnique.php
index 286d340..bd3e493 100644
--- a/core/modules/user/src/Plugin/Validation/Constraint/UserNameUnique.php
+++ b/core/modules/user/src/Plugin/Validation/Constraint/UserNameUnique.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\user\Plugin\Validation\Constraint;
 
-use Symfony\Component\Validator\Constraint;
+use Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldConstraint;
 
 /**
  * Checks if a user name is unique on the site.
@@ -17,14 +17,8 @@
  *   label = @Translation("User name unique", context = "Validation"),
  * )
  */
-class UserNameUnique extends Constraint {
+class UserNameUnique extends UniqueFieldConstraint {
 
   public $message = 'The username %value is already taken.';
 
-  /**
-   * {@inheritdoc}
-   */
-  public function validatedBy() {
-    return '\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator';
-  }
 }
