diff --git a/core/modules/content_moderation/src/EntityOperations.php b/core/modules/content_moderation/src/EntityOperations.php
index 51ad7d685d481eb3cbed40c132b46587fe42de7d..d76a35b983f59515fde084d3ab8a254197cfe68b 100644
--- a/core/modules/content_moderation/src/EntityOperations.php
+++ b/core/modules/content_moderation/src/EntityOperations.php
@@ -152,7 +152,6 @@ protected function updateOrCreateFromEntity(EntityInterface $entity) {
     $entity_type_id = $entity->getEntityTypeId();
     $entity_id = $entity->id();
     $entity_revision_id = $entity->getRevisionId();
-    $entity_langcode = $entity->language()->getId();
 
     $storage = $this->entityTypeManager->getStorage('content_moderation_state');
     $entities = $storage->loadByProperties([
@@ -174,11 +173,14 @@ protected function updateOrCreateFromEntity(EntityInterface $entity) {
     }
 
     // Sync translations.
-    if (!$content_moderation_state->hasTranslation($entity_langcode)) {
-      $content_moderation_state->addTranslation($entity_langcode);
-    }
-    if ($content_moderation_state->language()->getId() !== $entity_langcode) {
-      $content_moderation_state = $content_moderation_state->getTranslation($entity_langcode);
+    if ($entity->getEntityType()->hasKey('langcode')) {
+      $entity_langcode = $entity->language()->getId();
+      if (!$content_moderation_state->hasTranslation($entity_langcode)) {
+        $content_moderation_state->addTranslation($entity_langcode);
+      }
+      if ($content_moderation_state->language()->getId() !== $entity_langcode) {
+        $content_moderation_state = $content_moderation_state->getTranslation($entity_langcode);
+      }
     }
 
     // Create the ContentModerationState entity for the inserted entity.
diff --git a/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php
index 80820b4b4ebf32e93b5ede36bd1a0191fc0e2fd5..c32521c44ae8d0d3e7c807eedd2f1ec80ed911bf 100644
--- a/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php
+++ b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php
@@ -43,12 +43,14 @@ protected function getModerationState() {
           ->loadRevision($revision_to_load);
 
         // Return the correct translation.
-        $langcode = $entity->language()->getId();
-        if (!$content_moderation_state->hasTranslation($langcode)) {
-          $content_moderation_state->addTranslation($langcode);
-        }
-        if ($content_moderation_state->language()->getId() !== $langcode) {
-          $content_moderation_state = $content_moderation_state->getTranslation($langcode);
+        if ($entity->getEntityType()->hasKey('langcode')) {
+          $langcode = $entity->language()->getId();
+          if (!$content_moderation_state->hasTranslation($langcode)) {
+            $content_moderation_state->addTranslation($langcode);
+          }
+          if ($content_moderation_state->language()->getId() !== $langcode) {
+            $content_moderation_state = $content_moderation_state->getTranslation($langcode);
+          }
         }
 
         return $content_moderation_state->get('moderation_state')->entity;
diff --git a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
index 3ba37a294203082e77300d02d9e8c9f92780412e..67a7a749805fd348a0a72c7b9f9697e2c38ce656 100644
--- a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
+++ b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
@@ -4,6 +4,8 @@
 
 use Drupal\content_moderation\Entity\ContentModerationState;
 use Drupal\content_moderation\Entity\ModerationState;
+use Drupal\entity_test\Entity\EntityTestBundle;
+use Drupal\entity_test\Entity\EntityTestWithBundle;
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\node\Entity\Node;
@@ -21,12 +23,14 @@ class ContentModerationStateTest extends KernelTestBase {
    * {@inheritdoc}
    */
   public static $modules = [
+    'entity_test',
     'node',
     'content_moderation',
     'user',
     'system',
     'language',
     'content_translation',
+    'text',
   ];
 
   /**
@@ -38,6 +42,7 @@ protected function setUp() {
     $this->installSchema('node', 'node_access');
     $this->installEntitySchema('node');
     $this->installEntitySchema('user');
+    $this->installEntitySchema('entity_test_with_bundle');
     $this->installEntitySchema('content_moderation_state');
     $this->installConfig('content_moderation');
   }
@@ -210,6 +215,91 @@ public function testMultilingualModeration() {
     $this->assertEquals(6, $english_node->getRevisionId());
   }
 
+  /**
+   * Tests that a non-translatable entity type with a langcode can be moderated.
+   */
+  public function testNonTranslatableEntityTypeModeration() {
+    // Make the 'entity_test_with_bundle' entity type revisionable.
+    $entity_type = clone \Drupal::entityTypeManager()->getDefinition('entity_test_with_bundle');
+    $keys = $entity_type->getKeys();
+    $keys['revision'] = 'revision_id';
+    $entity_type->set('entity_keys', $keys);
+    \Drupal::state()->set('entity_test_with_bundle.entity_type', $entity_type);
+    \Drupal::entityDefinitionUpdateManager()->applyUpdates();
+
+    // Create a test bundle.
+    $entity_test_bundle = EntityTestBundle::create([
+      'id' => 'example',
+    ]);
+    $entity_test_bundle->setThirdPartySetting('content_moderation', 'enabled', TRUE);
+    $entity_test_bundle->setThirdPartySetting('content_moderation', 'allowed_moderation_states', [
+      'draft',
+      'published'
+    ]);
+    $entity_test_bundle->setThirdPartySetting('content_moderation', 'default_moderation_state', 'draft');
+    $entity_test_bundle->save();
+
+    // Check that the tested entity type is not translatable.
+    $entity_type = \Drupal::entityTypeManager()->getDefinition('entity_test_with_bundle');
+    $this->assertFalse($entity_type->isTranslatable(), 'The test entity type is not translatable.');
+
+    // Create a test entity.
+    $entity_test_with_bundle = EntityTestWithBundle::create([
+      'type' => 'example'
+    ]);
+    $entity_test_with_bundle->save();
+    $this->assertEquals('draft', $entity_test_with_bundle->moderation_state->entity->id());
+
+    $entity_test_with_bundle->moderation_state->target_id = 'published';
+    $entity_test_with_bundle->save();
+
+    $this->assertEquals('published', EntityTestWithBundle::load($entity_test_with_bundle->id())->moderation_state->entity->id());
+  }
+
+  /**
+   * Tests that a non-translatable entity type without a langcode can be
+   * moderated.
+   */
+  public function testNonLangcodeEntityTypeModeration() {
+    // Make the 'entity_test_with_bundle' entity type revisionable and unset
+    // the langcode entity key.
+    $entity_type = clone \Drupal::entityTypeManager()->getDefinition('entity_test_with_bundle');
+    $keys = $entity_type->getKeys();
+    $keys['revision'] = 'revision_id';
+    unset($keys['langcode']);
+    $entity_type->set('entity_keys', $keys);
+    \Drupal::state()->set('entity_test_with_bundle.entity_type', $entity_type);
+    \Drupal::entityDefinitionUpdateManager()->applyUpdates();
+
+    // Create a test bundle.
+    $entity_test_bundle = EntityTestBundle::create([
+      'id' => 'example',
+    ]);
+    $entity_test_bundle->setThirdPartySetting('content_moderation', 'enabled', TRUE);
+    $entity_test_bundle->setThirdPartySetting('content_moderation', 'allowed_moderation_states', [
+      'draft',
+      'published'
+    ]);
+    $entity_test_bundle->setThirdPartySetting('content_moderation', 'default_moderation_state', 'draft');
+    $entity_test_bundle->save();
+
+    // Check that the tested entity type is not translatable.
+    $entity_type = \Drupal::entityTypeManager()->getDefinition('entity_test_with_bundle');
+    $this->assertFalse($entity_type->isTranslatable(), 'The test entity type is not translatable.');
+
+    // Create a test entity.
+    $entity_test_with_bundle = EntityTestWithBundle::create([
+      'type' => 'example'
+    ]);
+    $entity_test_with_bundle->save();
+    $this->assertEquals('draft', $entity_test_with_bundle->moderation_state->entity->id());
+
+    $entity_test_with_bundle->moderation_state->target_id = 'published';
+    $entity_test_with_bundle->save();
+
+    $this->assertEquals('published', EntityTestWithBundle::load($entity_test_with_bundle->id())->moderation_state->entity->id());
+  }
+
   /**
    * Reloads the node after clearing the static cache.
    *
diff --git a/core/modules/system/tests/modules/entity_test/config/schema/entity_test.schema.yml b/core/modules/system/tests/modules/entity_test/config/schema/entity_test.schema.yml
index d34d94940dc0a5cbc29060a4d83232fabf68f55a..464a007ac61290092d9b413853efc1c3d3871f38 100644
--- a/core/modules/system/tests/modules/entity_test/config/schema/entity_test.schema.yml
+++ b/core/modules/system/tests/modules/entity_test/config/schema/entity_test.schema.yml
@@ -27,3 +27,19 @@ entity_test.entity_test_bundle.*:
     description:
       type: text
       label: 'Description'
+
+entity_test.entity_test_bundle.*.third_party.content_moderation:
+  type: mapping
+  label: 'Enable moderation states for this entity test type'
+  mapping:
+    enabled:
+      type: boolean
+      label: 'Moderation states enabled'
+    allowed_moderation_states:
+      type: sequence
+      sequence:
+        type: string
+        label: 'Moderation state'
+    default_moderation_state:
+      type: string
+      label: 'Moderation state for new entity test'
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module
index b0c8cbf4dccd14faa5cd75b59d09c1080b612334..f8f56ebbb0a492f7617c14805755cd58e8a1b881 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.module
+++ b/core/modules/system/tests/modules/entity_test/entity_test.module
@@ -95,12 +95,26 @@ function entity_test_entity_type_alter(array &$entity_types) {
   // Allow entity_test_update tests to override the entity type definition.
   $entity_types['entity_test_update'] = $state->get('entity_test_update.entity_type', $entity_types['entity_test_update']);
 
+  // Allow entity_test_with_bundle tests to override the entity type definition.
+  $entity_types['entity_test_with_bundle'] = $state->get('entity_test_with_bundle.entity_type', $entity_types['entity_test_with_bundle']);
+
   // Enable the entity_test_new only when needed.
   if (!$state->get('entity_test_new')) {
     unset($entity_types['entity_test_new']);
   }
 }
 
+/**
+ * Implements hook_module_implements_alter().
+ */
+function entity_test_module_implements_alter(&$implementations, $hook) {
+  // Move our hook_entity_type_alter() implementation to the beginning of the
+  // list in order to run before content_moderation_entity_type_alter().
+  if ($hook === 'entity_type_alter') {
+    $implementations = ['entity_test' => $implementations['entity_test']] + $implementations;
+  }
+}
+
 /**
  * Implements hook_entity_base_field_info().
  */