diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index d48b232..59c4b85 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -1212,6 +1212,10 @@ function template_preprocess_file_managed_file(&$variables) {
   if (!empty($element['#attributes']['class'])) {
     $variables['attributes']['class'] = (array) $element['#attributes']['class'];
   }
+
+  // Remove unnecessary double errors on file upload which results in bad UX.
+  unset($variables['element']['#prefix']);
+  unset($variables['element']['#suffix']);
 }
 
 /**
diff --git a/core/modules/file/src/Tests/FileFieldValidateTest.php b/core/modules/file/src/Tests/FileFieldValidateTest.php
index 291c432..5c4df4e 100644
--- a/core/modules/file/src/Tests/FileFieldValidateTest.php
+++ b/core/modules/file/src/Tests/FileFieldValidateTest.php
@@ -159,4 +159,26 @@ function testFileExtension() {
     $this->assertFileEntryExists($node_file, 'File entry exists after uploading a file with extension checking.');
   }
 
+  /**
+   * Test the validation message is displayed only once for ajax uploads.
+   */
+  public function testAJAXValidationMessages() {
+    $type_name = 'article';
+    $field_name = strtolower($this->randomMachineName());
+    $this->createFileField($field_name, 'node', $type_name);
+
+    $this->drupalGet('node/add/article');
+    /** @var \Drupal\file\FileInterface  $image_file */
+    $image_file = $this->getTestFile('image');
+    $edit = array(
+      'files[' . $field_name . '_0]' => $this->container->get('file_system')->realpath($image_file->getFileUri()),
+      'title[0][value]' => $this->randomMachineName(),
+    );
+    $this->drupalPostAjaxForm(NULL, $edit, $field_name . '_0_upload_button');
+    $elements = $this->xpath('//div[contains(@class, :class)]', array(
+      ':class' => 'messages--error',
+    ));
+    $this->assertEqual(count($elements), 1, 'Ajax validation messages are displayed once.');
+  }
+
 }
diff --git a/core/modules/image/src/Tests/ImageFieldValidateTest.php b/core/modules/image/src/Tests/ImageFieldValidateTest.php
index 3fee09c..50d0dc8 100644
--- a/core/modules/image/src/Tests/ImageFieldValidateTest.php
+++ b/core/modules/image/src/Tests/ImageFieldValidateTest.php
@@ -106,4 +106,25 @@ function testRequiredAttributes() {
     $this->assertNoText(t('Alternative text field is required.'));
     $this->assertNoText(t('Title field is required.'));
   }
+
+  /**
+   * Test the validation message is displayed only once for ajax uploads.
+   */
+  public function testAJAXValidationMessages() {
+    $field_name = strtolower($this->randomMachineName());
+    $this->createImageField($field_name, 'article', array(), array());
+
+    $this->drupalGet('node/add/article');
+    $text_files = $this->drupalGetTestFiles('text');
+    $text_file = reset($text_files);
+    $edit = array(
+      'files[' . $field_name . '_0]' => $this->container->get('file_system')->realpath($text_file->uri),
+      'title[0][value]' => $this->randomMachineName(),
+    );
+    $this->drupalPostAjaxForm(NULL, $edit, $field_name . '_0_upload_button');
+    $elements = $this->xpath('//div[contains(@class, :class)]', array(
+      ':class' => 'messages--error',
+    ));
+    $this->assertEqual(count($elements), 1, 'Ajax validation messages are displayed once.');
+  }
 }
