diff --git a/core/lib/Drupal/Core/Entity/EntityType.php b/core/lib/Drupal/Core/Entity/EntityType.php
index 3a32d4a..140ca2b 100644
--- a/core/lib/Drupal/Core/Entity/EntityType.php
+++ b/core/lib/Drupal/Core/Entity/EntityType.php
@@ -248,6 +248,9 @@ public function __construct($definition) {
     }
 
     foreach ($definition as $property => $value) {
+      if (!property_exists($this, $property)) {
+        throw new \InvalidArgumentException(sprintf('"%s" property does not exist on %s. Change the entity annotation for "%s" or extend this class.', $property, get_class($this), $definition['id']));
+      }
       $this->{$property} = $value;
     }
 
diff --git a/core/lib/Drupal/Core/Field/Entity/BaseFieldOverride.php b/core/lib/Drupal/Core/Field/Entity/BaseFieldOverride.php
index ecf7665..751693d 100644
--- a/core/lib/Drupal/Core/Field/Entity/BaseFieldOverride.php
+++ b/core/lib/Drupal/Core/Field/Entity/BaseFieldOverride.php
@@ -20,7 +20,7 @@
  * @ConfigEntityType(
  *   id = "base_field_override",
  *   label = @Translation("Base field override"),
- *   controllers = {
+ *   handlers = {
  *     "storage" = "Drupal\Core\Field\BaseFieldOverrideStorage"
  *   },
  *   config_prefix = "base_field_override",
diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index da02771..97915a0 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -5,6 +5,7 @@
  * Allows entities to be translated into different languages.
  */
 
+use Drupal\content_translation\ContentTranslationEntityType;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Entity\ContentEntityFormInterface;
 use Drupal\Core\Entity\ContentEntityInterface;
@@ -92,23 +93,15 @@ function content_translation_language_types_info_alter(array &$language_types) {
  *   \Drupal\content_translation\ContentTranslationHandler will be assumed.
  *   Every translation handler must implement
  *   \Drupal\content_translation\ContentTranslationHandlerInterface.
- * - content_translation_ui_skip: By default, entity types that do not have a
- *   canonical link template cannot be enabled for translation. Setting this key
- *   to TRUE overrides that. When that key is set, the Content Translation
- *   module will not provide any UI for translating the entity type, and the
- *   entity type should implement its own UI. This is useful for (e.g.) entity
- *   types that are embedded into others for editing (which would not need a
- *   canonical link, but could still support translation).
- * - content_translation_metadata: To implement its business logic the content
- *   translation UI relies on various metadata items describing the translation
- *   state. The default implementation is provided by
- *   \Drupal\content_translation\ContentTranslationMetadataWrapper, which is
- *   relying on one field for each metadata item (field definitions are provided
- *   by the translation handler). Entity types needing to customize this
- *   behavior can specify an alternative class through the
- *   'content_translation_metadata' key in the entity type definition. Every
- *   content translation metadata wrapper needs to implement
- *   \Drupal\content_translation\ContentTranslationMetadataWrapperInterface.
+ * - content_translation_ui_skip: See the $content_translation_ui_skip property
+ *   of \Drupal\content_translation\ContentTranslationEntityType.
+ * - content_translation_metadata: See the $content_translation_metadata
+ *   property of \Drupal\content_translation\ContentTranslationEntityType.
+ *
+ * In order to use content_translation_ui_skip or content_translation_metadata,
+ * the entity type must specify
+ * entity_type_class = "Drupal\content_translation\ContentTranslationEntityType"
+ * in its definition.
  *
  * If the entity paths match the default pattern above and there is no need for
  * an entity-specific translation handler, Content Translation will provide
@@ -127,6 +120,9 @@ function content_translation_entity_type_alter(array &$entity_types) {
       }
       if (!$entity_type->get('content_translation_metadata')) {
         $entity_type->set('content_translation_metadata', 'Drupal\content_translation\ContentTranslationMetadataWrapper');
+        // In order to use the content_translation_metadata property, we must
+        // switch the entity type class.
+        $entity_type->set('entity_type_class', ContentTranslationEntityType::class);
       }
       if (!$entity_type->getFormClass('content_translation_deletion')) {
         $entity_type->setFormClass('content_translation_deletion', '\Drupal\content_translation\Form\ContentTranslationDeleteForm');
diff --git a/core/modules/content_translation/src/ContentTranslationEntityType.php b/core/modules/content_translation/src/ContentTranslationEntityType.php
new file mode 100644
index 0000000..7dc232d
--- /dev/null
+++ b/core/modules/content_translation/src/ContentTranslationEntityType.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\content_translation\ContentTranslationEntityType.
+ */
+
+namespace Drupal\content_translation;
+
+use Drupal\Core\Entity\ContentEntityType;
+
+/**
+ * Subclasses ContentEntityType to add content translation entity type keys.
+ */
+class ContentTranslationEntityType extends ContentEntityType {
+
+  /**
+   * @todo Oneliner needed.
+   *
+   * By default, entity types that do not have a canonical link template cannot
+   * be enabled for translation. Setting this key to TRUE overrides that. When
+   * this key is set, the Content Translation module will not provide any UI for
+   * translating the entity type, and the entity type should implement its own
+   * UI. This is useful for (e.g.) entity types that are embedded into others
+   * for editing (which would not need a canonical link, but could still support
+   * translation).
+   *
+   * @var bool
+   */
+  protected $content_translation_ui_skip;
+
+  /**
+   * @todo Oneliner needed.
+   *
+   * To implement its business logic the content translation UI relies on
+   * various metadata items describing the translation state. The default
+   * implementation is provided by
+   * \Drupal\content_translation\ContentTranslationMetadataWrapper, which is
+   * relying on one field for each metadata item (field definitions are provided
+   * by the translation handler). Entity types needing to customize this
+   * behavior can specify an alternative class through this key in the entity
+   * type definition. Every content translation metadata wrapper needs to
+   * implement
+   * \Drupal\content_translation\ContentTranslationMetadataWrapperInterface.
+   *
+   * @var string
+   */
+  protected $content_translation_metadata;
+
+}
diff --git a/core/modules/content_translation/tests/modules/content_translation_test/src/Entity/EntityTestTranslatableUISkip.php b/core/modules/content_translation/tests/modules/content_translation_test/src/Entity/EntityTestTranslatableUISkip.php
index 10eb3c3..eea863f 100644
--- a/core/modules/content_translation/tests/modules/content_translation_test/src/Entity/EntityTestTranslatableUISkip.php
+++ b/core/modules/content_translation/tests/modules/content_translation_test/src/Entity/EntityTestTranslatableUISkip.php
@@ -25,6 +25,7 @@
  *     "langcode" = "langcode",
  *   },
  *   translatable = TRUE,
+ *   entity_type_class = "\Drupal\content_translation\ContentTranslationEntityType",
  *   content_translation_ui_skip = TRUE,
  * )
  */
diff --git a/core/modules/migrate/src/Entity/Migration.php b/core/modules/migrate/src/Entity/Migration.php
index c287e1f..262c21a 100644
--- a/core/modules/migrate/src/Entity/Migration.php
+++ b/core/modules/migrate/src/Entity/Migration.php
@@ -24,7 +24,7 @@
  * @ConfigEntityType(
  *   id = "migration",
  *   label = @Translation("Migration"),
- *   module = "migrate",
+ *   provider = "migrate",
  *   handlers = {
  *     "storage" = "Drupal\migrate\MigrationStorage"
  *   },
diff --git a/core/modules/responsive_image/src/Entity/ResponsiveImageStyle.php b/core/modules/responsive_image/src/Entity/ResponsiveImageStyle.php
index 34ae8d3..f3a2084 100644
--- a/core/modules/responsive_image/src/Entity/ResponsiveImageStyle.php
+++ b/core/modules/responsive_image/src/Entity/ResponsiveImageStyle.php
@@ -26,7 +26,6 @@
  *       "duplicate" = "Drupal\responsive_image\ResponsiveImageStyleForm"
  *     }
  *   },
- *   list_path = "admin/config/media/responsive-image-style",
  *   admin_permission = "administer responsive images",
  *   config_prefix = "styles",
  *   entity_keys = {
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestUpdate.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestUpdate.php
index 59a2648..41ce146 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestUpdate.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestUpdate.php
@@ -23,7 +23,6 @@
  *   },
  *   base_table = "entity_test_update",
  *   revision_table = "entity_test_update_revision",
- *   fieldable = TRUE,
  *   persistent_cache = FALSE,
  *   entity_keys = {
  *     "id" = "id",
