diff --git a/core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php b/core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php
index cae43980274a0c57cf1d1e9500bad79567f24fb4..6c9c1788f23310738bc35b390f97e8c2d1915333 100644
--- a/core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php
+++ b/core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php
@@ -3,7 +3,7 @@
 namespace Drupal\Core\Form\EventSubscriber;
 
 use Drupal\Core\Ajax\AjaxResponse;
-use Drupal\Core\Ajax\ReplaceCommand;
+use Drupal\Core\Ajax\PrependCommand;
 use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
 use Drupal\Core\Form\Exception\BrokenPostRequestException;
 use Drupal\Core\Form\FormAjaxException;
@@ -78,7 +78,7 @@ public function onException(GetResponseForExceptionEvent $event) {
       $this->drupalSetMessage($this->t('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@size) that this server supports.', ['@size' => $this->formatSize($exception->getSize())]), 'error');
       $response = new AjaxResponse();
       $status_messages = ['#type' => 'status_messages'];
-      $response->addCommand(new ReplaceCommand(NULL, $status_messages));
+      $response->addCommand(new PrependCommand(NULL, $status_messages));
       $response->headers->set('X-Status-Code', 200);
       $event->setResponse($response);
       return;
diff --git a/core/modules/file/tests/src/Functional/FileFieldCreationTrait.php b/core/modules/file/tests/src/Functional/FileFieldCreationTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..89c713e0779d096e61d0fca837b87b0077fd80f2
--- /dev/null
+++ b/core/modules/file/tests/src/Functional/FileFieldCreationTrait.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Drupal\Tests\file\Functional;
+
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\field\Entity\FieldConfig;
+
+/**
+ * Provides methods for creating file fields.
+ */
+trait FileFieldCreationTrait {
+
+  /**
+   * Creates a new file field.
+   *
+   * @param string $name
+   *   The name of the new field (all lowercase), exclude the "field_" prefix.
+   * @param string $entity_type
+   *   The entity type.
+   * @param string $bundle
+   *   The bundle that this field will be added to.
+   * @param array $storage_settings
+   *   A list of field storage settings that will be added to the defaults.
+   * @param array $field_settings
+   *   A list of instance settings that will be added to the instance defaults.
+   * @param array $widget_settings
+   *   A list of widget settings that will be added to the widget defaults.
+   *
+   * @return \Drupal\field\FieldStorageConfigInterface
+   *   The file field.
+   */
+  public function createFileField($name, $entity_type, $bundle, $storage_settings = [], $field_settings = [], $widget_settings = []) {
+    $field_storage = FieldStorageConfig::create([
+      'entity_type' => $entity_type,
+      'field_name' => $name,
+      'type' => 'file',
+      'settings' => $storage_settings,
+      'cardinality' => !empty($storage_settings['cardinality']) ? $storage_settings['cardinality'] : 1,
+    ]);
+    $field_storage->save();
+
+    $this->attachFileField($name, $entity_type, $bundle, $field_settings, $widget_settings);
+    return $field_storage;
+  }
+
+  /**
+   * Attaches a file field to an entity.
+   *
+   * @param string $name
+   *   The name of the new field (all lowercase), exclude the "field_" prefix.
+   * @param string $entity_type
+   *   The entity type this field will be added to.
+   * @param string $bundle
+   *   The bundle this field will be added to.
+   * @param array $field_settings
+   *   A list of field settings that will be added to the defaults.
+   * @param array $widget_settings
+   *   A list of widget settings that will be added to the widget defaults.
+   */
+  public function attachFileField($name, $entity_type, $bundle, $field_settings = [], $widget_settings = []) {
+    $field = [
+      'field_name' => $name,
+      'label' => $name,
+      'entity_type' => $entity_type,
+      'bundle' => $bundle,
+      'required' => !empty($field_settings['required']),
+      'settings' => $field_settings,
+    ];
+    FieldConfig::create($field)->save();
+
+    entity_get_form_display($entity_type, $bundle, 'default')
+      ->setComponent($name, [
+        'type' => 'file_generic',
+        'settings' => $widget_settings,
+      ])
+      ->save();
+    // Assign display settings.
+    entity_get_display($entity_type, $bundle, 'default')
+      ->setComponent($name, [
+        'label' => 'hidden',
+        'type' => 'file_default',
+      ])
+      ->save();
+  }
+
+}
diff --git a/core/modules/file/tests/src/Functional/FileFieldTestBase.php b/core/modules/file/tests/src/Functional/FileFieldTestBase.php
index d6096874d68bd2f6549a56e80070f72bca83b2e0..16733144e31e792063bfa434ccf09770cc055e50 100644
--- a/core/modules/file/tests/src/Functional/FileFieldTestBase.php
+++ b/core/modules/file/tests/src/Functional/FileFieldTestBase.php
@@ -13,6 +13,8 @@
  */
 abstract class FileFieldTestBase extends BrowserTestBase {
 
+  use FileFieldCreationTrait;
+
   /**
   * Modules to enable.
   *
@@ -57,76 +59,6 @@ public function getLastFileId() {
     return (int) db_query('SELECT MAX(fid) FROM {file_managed}')->fetchField();
   }
 
-  /**
-   * Creates a new file field.
-   *
-   * @param string $name
-   *   The name of the new field (all lowercase), exclude the "field_" prefix.
-   * @param string $entity_type
-   *   The entity type.
-   * @param string $bundle
-   *   The bundle that this field will be added to.
-   * @param array $storage_settings
-   *   A list of field storage settings that will be added to the defaults.
-   * @param array $field_settings
-   *   A list of instance settings that will be added to the instance defaults.
-   * @param array $widget_settings
-   *   A list of widget settings that will be added to the widget defaults.
-   */
-  public function createFileField($name, $entity_type, $bundle, $storage_settings = [], $field_settings = [], $widget_settings = []) {
-    $field_storage = FieldStorageConfig::create([
-      'entity_type' => $entity_type,
-      'field_name' => $name,
-      'type' => 'file',
-      'settings' => $storage_settings,
-      'cardinality' => !empty($storage_settings['cardinality']) ? $storage_settings['cardinality'] : 1,
-    ]);
-    $field_storage->save();
-
-    $this->attachFileField($name, $entity_type, $bundle, $field_settings, $widget_settings);
-    return $field_storage;
-  }
-
-  /**
-   * Attaches a file field to an entity.
-   *
-   * @param string $name
-   *   The name of the new field (all lowercase), exclude the "field_" prefix.
-   * @param string $entity_type
-   *   The entity type this field will be added to.
-   * @param string $bundle
-   *   The bundle this field will be added to.
-   * @param array $field_settings
-   *   A list of field settings that will be added to the defaults.
-   * @param array $widget_settings
-   *   A list of widget settings that will be added to the widget defaults.
-   */
-  public function attachFileField($name, $entity_type, $bundle, $field_settings = [], $widget_settings = []) {
-    $field = [
-      'field_name' => $name,
-      'label' => $name,
-      'entity_type' => $entity_type,
-      'bundle' => $bundle,
-      'required' => !empty($field_settings['required']),
-      'settings' => $field_settings,
-    ];
-    FieldConfig::create($field)->save();
-
-    entity_get_form_display($entity_type, $bundle, 'default')
-      ->setComponent($name, [
-        'type' => 'file_generic',
-        'settings' => $widget_settings,
-      ])
-      ->save();
-    // Assign display settings.
-    entity_get_display($entity_type, $bundle, 'default')
-      ->setComponent($name, [
-        'label' => 'hidden',
-        'type' => 'file_default',
-      ])
-      ->save();
-  }
-
   /**
    * Updates an existing file field with new settings.
    */
diff --git a/core/modules/file/tests/src/FunctionalJavascript/MaximumFileSizeExceededUploadTest.php b/core/modules/file/tests/src/FunctionalJavascript/MaximumFileSizeExceededUploadTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ccd2b218737f8f3582301bf91e1f36d6aa3b4ec
--- /dev/null
+++ b/core/modules/file/tests/src/FunctionalJavascript/MaximumFileSizeExceededUploadTest.php
@@ -0,0 +1,119 @@
+<?php
+
+namespace Drupal\Tests\file\FunctionalJavascript;
+
+use Drupal\Component\Utility\Bytes;
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+use Drupal\Tests\TestFileCreationTrait;
+use Drupal\Tests\file\Functional\FileFieldCreationTrait;
+
+/**
+ * Tests uploading a file that exceeds the maximum file size.
+ *
+ * @group file
+ */
+class MaximumFileSizeExceededUploadTest extends JavascriptTestBase {
+
+  use FileFieldCreationTrait;
+  use TestFileCreationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node', 'file'];
+
+  /**
+   * The file system service.
+   *
+   * @var \Drupal\Core\File\FileSystemInterface
+   */
+  protected $fileSystem;
+
+  /**
+   * A test user.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $user;
+
+  /**
+   * The original value of the 'display_errors' PHP configuration option.
+   *
+   * @todo Remove this when issue #2905597 is fixed.
+   * @see https://www.drupal.org/node/2905597
+   *
+   * @var string
+   */
+  protected $originalDisplayErrorsValue;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->fileSystem = $this->container->get('file_system');
+
+    // Create the Article node type.
+    $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
+
+    // Attach a file field to the node type.
+    $field_settings = ['file_extensions' => 'txt'];
+    $this->createFileField('field_file', 'node', 'article', [], $field_settings);
+
+    // Log in as a content author who can create Articles.
+    $this->user = $this->drupalCreateUser([
+      'access content',
+      'create article content',
+    ]);
+    $this->drupalLogin($this->user);
+
+    // Disable the displaying of errors, so that the AJAX responses are not
+    // contaminated with error messages about exceeding the maximum POST size.
+    // @todo Remove this when issue #2905597 is fixed.
+    // @see https://www.drupal.org/node/2905597
+    $this->originalDisplayErrorsValue = ini_set('display_errors', '0');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function tearDown() {
+    // Restore the displaying of errors to the original value.
+    // @todo Remove this when issue #2905597 is fixed.
+    // @see https://www.drupal.org/node/2905597
+    ini_set('display_errors', $this->originalDisplayErrorsValue);
+
+    parent::tearDown();
+  }
+
+  /**
+   * Tests that uploading files exceeding maximum size are handled correctly.
+   */
+  public function testUploadFileExceedingMaximumFileSize() {
+    $session = $this->getSession();
+
+    // Create a test file that exceeds the maximum POST size with 1 kilobyte.
+    $post_max_size = Bytes::toInt(ini_get('post_max_size'));
+    $invalid_file = $this->generateFile('exceeding_post_max_size', ceil(($post_max_size + 1024) / 1024), 1024);
+
+    // Go to the node creation form and try to upload the test file.
+    $this->drupalGet('node/add/article');
+    $page = $session->getPage();
+    $page->attachFileToField("files[field_file_0]", $this->fileSystem->realpath($invalid_file));
+
+    // An error message should appear informing the user that the file exceeded
+    // the maximum file size.
+    $this->assertSession()->waitForElement('css', '.messages--error');
+    // The error message includes the actual file size limit which depends on
+    // the current environment, so we check for a part of the message.
+    $this->assertSession()->pageTextContains('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size');
+
+    // Now upload a valid file and check that the error message disappears.
+    $valid_file = $this->generateFile('not_exceeding_post_max_size', 8, 8);
+    $page->attachFileToField("files[field_file_0]", $this->fileSystem->realpath($valid_file));
+    $this->assertSession()->waitForElement('named', ['id_or_name', 'field_file_0_remove_button']);
+    $this->assertSession()->elementNotExists('css', '.messages--error');
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Form/EventSubscriber/FormAjaxSubscriberTest.php b/core/tests/Drupal/Tests/Core/Form/EventSubscriber/FormAjaxSubscriberTest.php
index 050d74526508767bac2f0e1c5dd49255b30bb354..278ec064166826dd4ab7f146057ffd4b2a93d9a0 100644
--- a/core/tests/Drupal/Tests/Core/Form/EventSubscriber/FormAjaxSubscriberTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/EventSubscriber/FormAjaxSubscriberTest.php
@@ -181,7 +181,7 @@ public function testOnExceptionBrokenPostRequest() {
     $this->assertSame(200, $actual_response->headers->get('X-Status-Code'));
     $expected_commands[] = [
       'command' => 'insert',
-      'method' => 'replaceWith',
+      'method' => 'prepend',
       'selector' => NULL,
       'data' => $rendered_output,
       'settings' => NULL,
diff --git a/core/tests/Drupal/Tests/TestFileCreationTrait.php b/core/tests/Drupal/Tests/TestFileCreationTrait.php
index 5bb5394be99620a74b5636d99c39522f085f5e3a..a2f119b65ca4a4b51f7dee2e44edcf1457ec4bd7 100644
--- a/core/tests/Drupal/Tests/TestFileCreationTrait.php
+++ b/core/tests/Drupal/Tests/TestFileCreationTrait.php
@@ -164,7 +164,8 @@ public static function generateFile($filename, $width, $lines, $type = 'binary-t
     }
 
     // Create filename.
-    file_put_contents('public://' . $filename . '.txt', $text);
+    $filename = 'public://' . $filename . '.txt';
+    file_put_contents($filename, $text);
     return $filename;
   }