diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index 534048c..2300f60 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -9,6 +9,8 @@
 
 use Drupal\Core\DependencyInjection\DependencySerialization;
 use Drupal\Component\Utility\String;
+use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Config\Entity\Exception\ConfigEntityIdLengthException;
 use Drupal\Core\Entity\Exception\UndefinedLinkTemplateException;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Session\AccountInterface;
@@ -336,6 +338,18 @@ public function getEntityType() {
    * {@inheritdoc}
    */
   public function preSave(EntityStorageInterface $storage) {
+    // Check if this is an entity bundle.
+    if ($this->getEntityType()->getBundleOf()) {
+      // Throw an exception if the bundle ID is longer than 32 characters.
+      if (Unicode::strlen($this->id()) > EntityTypeInterface::BUNDLE_MAX_LENGTH) {
+        throw new ConfigEntityIdLengthException(String::format(
+          'Attempt to create a bundle with an ID longer than @max characters: @id.', array(
+            '@max' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
+            '@id' => $this->id(),
+          )
+        ));
+      }
+    }
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php
index 93f6062..de4411c 100644
--- a/core/lib/Drupal/Core/Entity/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/EntityType.php
@@ -7,7 +7,9 @@
 
 namespace Drupal\Core\Entity;
 
+use Drupal\Component\Utility\String;
 use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Entity\Exception\EntityTypeIdLengthException;
 
 /**
  * Provides an implementation of an entity type and its metadata.
@@ -182,8 +184,21 @@ class EntityType implements EntityTypeInterface {
    *
    * @param array $definition
    *   An array of values from the annotation.
+   *
+   * @throws \Drupal\Core\Entity\Exception\EntityTypeIdLengthException
+   *   Thrown when attempting to instantiate an entity type with too long ID.
    */
   public function __construct($definition) {
+    // Throw an exception if the entity type ID is longer than 32 characters.
+    if (Unicode::strlen($definition['id']) > static::ID_MAX_LENGTH) {
+      throw new EntityTypeIdLengthException(String::format(
+        'Attempt to create an entity type with an ID longer than @max characters: @id.', array(
+          '@max' => static::ID_MAX_LENGTH,
+          '@id' => $definition['id'],
+        )
+      ));
+    }
+
     foreach ($definition as $property => $value) {
       $this->{$property} = $value;
     }
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
index 17d9555..b7b9d0d 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
@@ -18,6 +18,16 @@
 interface EntityTypeInterface {
 
   /**
+   * The maximum length of ID, in characters.
+   */
+  const ID_MAX_LENGTH = 32;
+
+  /**
+   * The maximum length of bundle name, in characters.
+   */
+  const BUNDLE_MAX_LENGTH = 32;
+
+  /**
    * Gets any arbitrary property.
    *
    * @param string $property
diff --git a/core/lib/Drupal/Core/Entity/Exception/EntityTypeIdLengthException.php b/core/lib/Drupal/Core/Entity/Exception/EntityTypeIdLengthException.php
new file mode 100644
index 0000000..e1a4feb
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Exception/EntityTypeIdLengthException.php
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Entity\Exception\EntityTypeIdLengthException.
+ */
+
+namespace Drupal\Core\Entity\Exception;
+
+/**
+ * Defines an exception thrown when an entity ID is too long.
+ */
+class EntityTypeIdLengthException extends \Exception { }
diff --git a/core/modules/block/custom_block/custom_block.install b/core/modules/block/custom_block/custom_block.install
index 3474559..6c27dd9 100644
--- a/core/modules/block/custom_block/custom_block.install
+++ b/core/modules/block/custom_block/custom_block.install
@@ -5,6 +5,8 @@
  * Install, update and uninstall functions for the custom block module.
  */
 
+use Drupal\Core\Entity\EntityTypeInterface;
+
 /**
  * Implements hook_schema().
  */
@@ -44,7 +46,7 @@ function custom_block_schema() {
       'type' => array(
         'description' => 'The type of this custom block.',
         'type' => 'varchar',
-        'length' => 32,
+        'length' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -64,7 +66,7 @@ function custom_block_schema() {
     ),
     'primary key' => array('id'),
     'indexes' => array(
-      'block_custom_type'   => array(array('type', 4)),
+      'block_custom_type' => array('type'),
     ),
     'unique keys' => array(
       'revision_id' => array('revision_id'),
@@ -161,7 +163,7 @@ function custom_block_schema_0() {
       'type' => array(
         'description' => 'The type of this custom block.',
         'type' => 'varchar',
-        'length' => 32,
+        'length' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
         'not null' => TRUE,
         'default' => '',
       ),
@@ -181,7 +183,7 @@ function custom_block_schema_0() {
     ),
     'primary key' => array('id'),
     'indexes' => array(
-      'block_custom_type'   => array(array('type', 4)),
+      'block_custom_type' => array('type'),
     ),
     'unique keys' => array(
       'revision_id' => array('revision_id'),
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php
index 5758788..a2f3008 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php
@@ -8,6 +8,7 @@
 namespace Drupal\custom_block;
 
 use Drupal\Core\Entity\EntityFormController;
+use Drupal\Core\Entity\EntityTypeInterface;
 
 /**
  * Base form controller for category edit forms.
@@ -36,6 +37,7 @@ public function form(array $form, array &$form_state) {
       '#machine_name' => array(
         'exists' => 'custom_block_type_load',
       ),
+      '#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
       '#disabled' => !$block_type->isNew(),
     );
 
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php
index 421e3b5..be01107 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php
@@ -190,7 +190,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
     $fields['type'] = FieldDefinition::create('entity_reference')
       ->setLabel(t('Block type'))
       ->setDescription(t('The block type.'))
-      ->setSetting('target_type', 'custom_block_type');
+      ->setSetting('target_type', 'custom_block_type')
+      ->setSetting('max_length', EntityTypeInterface::BUNDLE_MAX_LENGTH);
 
     $fields['log'] = FieldDefinition::create('string')
       ->setLabel(t('Revision log message'))
diff --git a/core/modules/comment/tests/Drupal/comment/Tests/Entity/CommentLockTest.php b/core/modules/comment/tests/Drupal/comment/Tests/Entity/CommentLockTest.php
index 5ba7f5e..2101d93 100644
--- a/core/modules/comment/tests/Drupal/comment/Tests/Entity/CommentLockTest.php
+++ b/core/modules/comment/tests/Drupal/comment/Tests/Entity/CommentLockTest.php
@@ -7,6 +7,7 @@
 namespace Drupal\comment\Tests\Entity;
 
 use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Entity\EntityType;
 use Drupal\Tests\UnitTestCase;
 
 /**
@@ -74,10 +75,16 @@ public function testLocks() {
     $comment->expects($this->any())
       ->method('getThread')
       ->will($this->returnValue(''));
-    $comment->expects($this->at(0))
+
+    $entity_type = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
+    $comment->expects($this->any())
+      ->method('getEntityType')
+      ->will($this->returnValue($entity_type));
+    $comment->expects($this->at(1))
       ->method('get')
       ->with('status')
       ->will($this->returnValue((object) array('value' => NULL)));
+
     $storage = $this->getMock('Drupal\comment\CommentStorageInterface');
     $comment->preSave($storage);
     $comment->postSave($storage);
diff --git a/core/modules/content_translation/content_translation.install b/core/modules/content_translation/content_translation.install
index 2d4963e..8ff4c7e 100644
--- a/core/modules/content_translation/content_translation.install
+++ b/core/modules/content_translation/content_translation.install
@@ -5,6 +5,7 @@
  * Installation functions for Content Translation module.
  */
 
+use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Language\Language;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
 
@@ -17,7 +18,7 @@ function content_translation_schema() {
     'fields' => array(
       'entity_type' => array(
         'type' => 'varchar',
-        'length' => 128,
+        'length' => EntityTypeInterface::ID_MAX_LENGTH,
         'not null' => TRUE,
         'default' => '',
         'description' => 'The entity type this translation relates to',
diff --git a/core/modules/node/lib/Drupal/node/NodeTypeFormController.php b/core/modules/node/lib/Drupal/node/NodeTypeFormController.php
index 7d6bd72..63f36f9 100644
--- a/core/modules/node/lib/Drupal/node/NodeTypeFormController.php
+++ b/core/modules/node/lib/Drupal/node/NodeTypeFormController.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Entity\EntityFormController;
 use Drupal\Component\Utility\String;
+use Drupal\Core\Entity\EntityTypeInterface;
 
 /**
  * Form controller for node type forms.
@@ -45,7 +46,7 @@ public function form(array $form, array &$form_state) {
     $form['type'] = array(
       '#type' => 'machine_name',
       '#default_value' => $type->id(),
-      '#maxlength' => 32,
+      '#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
       '#disabled' => $type->isLocked(),
       '#machine_name' => array(
         'exists' => 'node_type_load',
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php
index bbbed9c..0107003 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Entity/Term.php
@@ -122,7 +122,8 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
     $fields['vid'] = FieldDefinition::create('entity_reference')
       ->setLabel(t('Vocabulary'))
       ->setDescription(t('The vocabulary to which the term is assigned.'))
-      ->setSetting('target_type', 'taxonomy_vocabulary');
+      ->setSetting('target_type', 'taxonomy_vocabulary')
+      ->setSetting('max_length', EntityTypeInterface::BUNDLE_MAX_LENGTH);
 
     $fields['langcode'] = FieldDefinition::create('language')
       ->setLabel(t('Language code'))
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
index 4394ab0..6843596 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
@@ -258,14 +258,19 @@ function testTermAutocompletion() {
     $third_term->save();
 
     // Try to autocomplete a term name that matches both terms.
-    // We should get both term in a json encoded string.
+    // We should get both terms in a json encoded string.
     $input = '10/';
     $path = 'taxonomy/autocomplete/node/taxonomy_' . $this->vocabulary->id();
     // The result order is not guaranteed, so check each term separately.
     $result = $this->drupalGet($path, array('query' => array('q' => $input)));
+    // Pull the label properties from the array of arrays.
     $data = Json::decode($result);
-    $this->assertEqual($data[0]['label'], String::checkPlain($first_term->getName()), 'Autocomplete returned the first matching term');
-    $this->assertEqual($data[1]['label'], String::checkPlain($second_term->getName()), 'Autocomplete returned the second matching term');
+    $data = array_map(function ($item) {
+      return $item['label'];
+    }, $data);
+
+    $this->assertTrue(in_array(String::checkPlain($first_term->getName()), $data), 'Autocomplete returned the first matching term');
+    $this->assertTrue(in_array(String::checkPlain($second_term->getName()), $data), 'Autocomplete returned the second matching term');
 
     // Try to autocomplete a term name that matches first term.
     // We should only get the first term in a json encoded string.
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php
index 3474bfb..c446c28 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/VocabularyFormController.php
@@ -8,6 +8,7 @@
 namespace Drupal\taxonomy;
 
 use Drupal\Core\Entity\EntityFormController;
+use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Language\Language;
 
 /**
@@ -37,7 +38,7 @@ public function form(array $form, array &$form_state) {
     $form['vid'] = array(
       '#type' => 'machine_name',
       '#default_value' => $vocabulary->id(),
-      '#maxlength' => 255,
+      '#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
       '#machine_name' => array(
         'exists' => 'taxonomy_vocabulary_load',
         'source' => array('name'),
diff --git a/core/modules/taxonomy/taxonomy.install b/core/modules/taxonomy/taxonomy.install
index f76d350..a3f7e12 100644
--- a/core/modules/taxonomy/taxonomy.install
+++ b/core/modules/taxonomy/taxonomy.install
@@ -5,6 +5,8 @@
  * Install, update and uninstall functions for the taxonomy module.
  */
 
+use Drupal\Core\Entity\EntityTypeInterface;
+
 /**
  * Implements hook_schema().
  */
@@ -26,7 +28,7 @@ function taxonomy_schema() {
       ),
       'vid' => array(
         'type' => 'varchar',
-        'length' => 255,
+        'length' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
         'not null' => TRUE,
         'default' => '',
         'description' => 'The ID of the vocabulary to which the term is assigned.',
@@ -75,8 +77,8 @@ function taxonomy_schema() {
       'uuid' => array('uuid'),
     ),
     'indexes' => array(
-      'taxonomy_tree' => array(array('vid', 64), 'weight', 'name'),
-      'vid_name' => array(array('vid', 64), 'name'),
+      'taxonomy_tree' => array('vid', 'weight', 'name'),
+      'vid_name' => array('vid', 'name'),
       'name' => array('name'),
     ),
   );
diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityTypeTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityTypeTest.php
index 6befb00..3db843a 100644
--- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityTypeTest.php
+++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityTypeTest.php
@@ -30,104 +30,62 @@ public static function getInfo() {
     );
   }
 
-
   /**
-   * Tests that we get an exception when the length of the config prefix that is
-   * returned by getConfigPrefix() exceeds the maximum defined prefix length.
+   * Sets up a ConfigEntityType object for a given set of values.
    *
-   * @dataProvider providerPrefixLengthExceeds
-   * @covers ::getConfigPrefix()
+   * @param array $definition
+   *   An array of values to use for the ConfigEntityType.
+   *
+   * @return \Drupal\Core\Entity\EntityTypeInterface
    */
-  public function testConfigPrefixLengthExceeds($entity_data, $exception, $message) {
-    $config_entity = new ConfigEntityType($entity_data);
-    $this->setExpectedException($exception, $message);
-    $this->assertEmpty($config_entity->getConfigPrefix());
+  protected function setUpConfigEntityType($definition) {
+    if (!isset($definition['id'])) {
+      $definition += array(
+        'id' => 'example_config_entity_type',
+      );
+    }
+    return new ConfigEntityType($definition);
   }
 
   /**
-   * Provides arguments to instantiate a ConfigEntityType with a configuration
-   * entity prefix that exceeds the maximum character length.
+   * Tests that we get an exception when the length of the config prefix that is
+   * returned by getConfigPrefix() exceeds the maximum defined prefix length.
    *
-   * @return array
+   * @covers ::getConfigPrefix()
    */
-  public function providerPrefixLengthExceeds() {
-    $test_parameters = array();
+  public function testConfigPrefixLengthExceeds() {
     $message_text = 'The configuration file name prefix @config_prefix exceeds the maximum character limit of @max_char.';
 
-    // A provider length of 24 and id length of 59 (+1 for the .) results
-    // in a config length of 84, which is too long.
-    $entity_data = array(
-      'provider' => $this->randomName(24),
-      'id' => $this->randomName(59),
-    );
-    $test_parameters[] = array(
-      $entity_data,
-      '\Drupal\Core\Config\ConfigPrefixLengthException',
-      String::format($message_text, array(
-        '@config_prefix' => $entity_data['provider'] . '.' . $entity_data['id'],
-        '@max_char' => ConfigEntityType::PREFIX_LENGTH,
-      )),
-    );
-
     // A provider length of 24 and config_prefix length of 59 (+1 for the .)
     // results in a config length of 84, which is too long.
-    $entity_data = array(
+    $definition = array(
       'provider' => $this->randomName(24),
       'config_prefix' => $this->randomName(59),
     );
-    $test_parameters[] = array(
-      $entity_data,
-      '\Drupal\Core\Config\ConfigPrefixLengthException',
-      String::format($message_text, array(
-        '@config_prefix' => $entity_data['provider'] . '.' . $entity_data['config_prefix'],
-        '@max_char' => ConfigEntityType::PREFIX_LENGTH,
-      )),
-    );
-
-    return $test_parameters;
+    $config_entity = $this->setUpConfigEntityType($definition);
+    $this->setExpectedException('\Drupal\Core\Config\ConfigPrefixLengthException', String::format($message_text, array(
+      '@config_prefix' => $definition['provider'] . '.' . $definition['config_prefix'],
+      '@max_char' => ConfigEntityType::PREFIX_LENGTH,
+    )));
+    $this->assertEmpty($config_entity->getConfigPrefix());
   }
 
   /**
    * Tests that a valid config prefix returned by getConfigPrefix()
    * does not throw an exception and is formatted as expected.
    *
-   * @dataProvider providerPrefixLengthValid
    * @covers ::getConfigPrefix()
    */
-  public function testConfigPrefixLengthValid($entity_data) {
-    $config_entity = new ConfigEntityType($entity_data);
-    if (isset($entity_data['config_prefix'])) {
-      $expected_prefix = $entity_data['provider'] . '.' . $entity_data['config_prefix'];
-    } else {
-      $expected_prefix = $entity_data['provider'] . '.' . $entity_data['id'];
-    }
-    $this->assertEquals($expected_prefix, $config_entity->getConfigPrefix());
-  }
-
-  /**
-   * Provides arguments to instantiate a ConfigEntityType with a configuration
-   * entity prefix that does not exceed the maximum character length.
-   *
-   * @return array
-   */
-  public function providerPrefixLengthValid() {
-    $test_parameters = array();
-
+  public function testConfigPrefixLengthValid() {
     // A provider length of 24 and config_prefix length of 58 (+1 for the .)
     // results in a config length of 83, which is right at the limit.
-    $test_parameters[] = array(array(
+    $definition = array(
       'provider' => $this->randomName(24),
       'config_prefix' => $this->randomName(58),
-    ));
-
-    // A provider length of 24 and id length of 58 (+1 for the .) results in a
-    // config length of 83, which is right at the limit.
-    $test_parameters[] = array(array(
-      'provider' => $this->randomName(24),
-      'id' => $this->randomName(58),
-    ));
-
-    return $test_parameters;
+    );
+    $config_entity = $this->setUpConfigEntityType($definition);
+    $expected_prefix = $definition['provider'] . '.' . $definition['config_prefix'];
+    $this->assertEquals($expected_prefix, $config_entity->getConfigPrefix());
   }
 
 }
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
index d26ccd1..1cb561c 100644
--- a/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/EntityTypeTest.php
@@ -11,7 +11,7 @@
 use Drupal\Tests\UnitTestCase;
 
 /**
- * Tests the \Drupal\Core\Entity\EntityType class.
+ * @coversDefaultClass \Drupal\Core\Entity\EntityType
  *
  * @group Drupal
  * @group Entity
@@ -38,6 +38,9 @@ public static function getInfo() {
    * @return \Drupal\Core\Entity\EntityTypeInterface
    */
   protected function setUpEntityType($definition) {
+    $definition += array(
+      'id' => 'example_entity_type',
+    );
     return new EntityType($definition);
   }
 
@@ -191,6 +194,25 @@ public function testGetViewBuilderClass() {
   }
 
   /**
+   * @covers ::__construct
+   */
+  public function testIdExceedsMaxLength() {
+    $id = $this->randomName(33);
+    $message = 'Attempt to create an entity type with an ID longer than 32 characters: ' . $id;
+    $this->setExpectedException('Drupal\Core\Entity\Exception\EntityTypeIdLengthException', $message);
+    $this->setUpEntityType(array('id' => $id));
+  }
+
+  /**
+   * @covers ::id
+   */
+  public function testId() {
+    $id = $this->randomName(32);
+    $entity_type = $this->setUpEntityType(array('id' => $id));
+    $this->assertEquals($id, $entity_type->id());
+  }
+
+  /**
    * Gets a mock controller class name.
    *
    * @return string
