diff -u b/src/Form/MediaBulkUploadForm.php b/src/Form/MediaBulkUploadForm.php
--- b/src/Form/MediaBulkUploadForm.php
+++ b/src/Form/MediaBulkUploadForm.php
@@ -5,7 +5,10 @@
 use Drupal;
 use Drupal\Component\Utility\Bytes;
 use Drupal\Component\Utility\Environment;
+use Drupal\Core\Entity\EntityConstraintViolationListInterface;
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\Core\File\FileSystemInterface;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
@@ -407,6 +410,7 @@
     try {
       $media = $this->processFile($mediaBulkConfig, $file);
       if ($this->mediaSubFormManager->validateMediaFormDisplayUse($operation_details['media_bulk_config'])) {
+        /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $mediaFormDisplay */
         $extracted = $mediaFormDisplay->extractFormValues($media, $form['fields']['shared'], $form_state);
         $this->copyFormValuesToEntity($media, $extracted, $form_state);
       }
@@ -606,13 +610,60 @@
    *   Media Bulk Upload Form.
    */
   protected function prepareFormValues(FormStateInterface $form_state) {
+    $shared = (array) $form_state->getValue(['fields', 'shared']);
+    $shared_field_updated = FALSE;
+    // Check if we have entities that need to be created before starting the
+    // batch process.
+    foreach ($shared as $name => $value) {
+      if (empty($value['target_id']) || !is_array($value['target_id'])) {
+        continue;
+      }
+      foreach ($value['target_id'] as $delta => $item) {
+        if (empty($item['entity']) || !($item['entity'] instanceof EntityInterface)) {
+          continue;
+        }
+        $entity = $item['entity'];
+        if ($entity->isNew()) {
+          try {
+            // If it's a new entity, then attempt to reference the target
+            // ID instead to avoid accidental creation of duplicate.
+            unset($shared[$name]['target_id'][$delta]['entity']);
+            $shared_field_updated = TRUE;
+            if ($entity instanceof FieldableEntityInterface) {
+              $violations = $entity->validate();
+              $violations->filterByFieldAccess();
+              if ($violations->count()) {
+                throw new \RuntimeException(
+                  sprintf('Entity validation failed: %s', implode(' || ', $this->getViolationErrorMessages($violations)))
+                );
+              }
+            }
+            // No validation errors. Save, then use the entity target ID
+            // instead.
+            $entity->save();
+            $shared[$name]['target_id'][$delta]['target_id'] = $entity->id();
+          }
+          catch (\Exception $e) {
+            $args = [
+              '%field' => $name,
+            ];
+            watchdog_exception('media_bulk_upload', $e, 'Could not create entity for field %field.', $args);
+            $this->messenger()->addError($this->t('Failed to create entity for field %field.', $args), 'error');
+          }
+        }
+      }
+    }
+
     // If the shared name is empty, remove it from the form state.
     // Otherwise the extractFormValues function will override with an empty value.
-    $shared = $form_state->getValue(['fields', 'shared']);
     if (empty($shared['name'][0]['value'])) {
       unset($shared['name']);
+      $shared_field_updated = TRUE;
+    }
+    if ($shared_field_updated) {
       $form_state->setValue(['fields', 'shared'], $shared);
     }
+
     return $this;
   }
 
@@ -630,16 +681,7 @@
     $violations = $media->validate();
     $violations->filterByFieldAccess();
     if ($violations->count()) {
-      $errors = [];
-      /** @var \Symfony\Component\Validator\ConstraintViolationInterface $violation */
-      foreach ($violations as $violation) {
-        if ($violation->getPropertyPath()) {
-          $errors[] = sprintf('%s=%s', $violation->getPropertyPath(), $violation->getMessage());
-        }
-        else {
-          $errors[] = $violation->getMessage();
-        }
-      }
+      $errors = $this->getViolationErrorMessages($violations);
       $file_id = $media->getSource()->getSourceFieldValue($media);
       if ($file_id && $file = $this->fileStorage->load($file_id)) {
         // Delete the underlying file entity.
@@ -664,2 +706,24 @@
 
+  /**
+   * Returns the violation error messages as an array.
+   *
+   * @param \Drupal\Core\Entity\EntityConstraintViolationListInterface $violations
+   *   The entity violations.
+   *
+   * @return array
+   *   The list of entity violation messages.
+   */
+  protected function getViolationErrorMessages(EntityConstraintViolationListInterface $violations) {
+    $errors = [];
+    foreach ($violations as $violation) {
+      if ($violation->getPropertyPath()) {
+        $errors[] = sprintf('%s=%s', $violation->getPropertyPath(), $violation->getMessage());
+      }
+      else {
+        $errors[] = $violation->getMessage();
+      }
+    }
+    return $errors;
+  }
+
 }
