diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 687a62c70b..9f37d1363d 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -674,8 +674,83 @@ function file_cron() {
 }
 
 /**
+ * Saves form file uploads.
+ *
+ * The files will be added to the {file_managed} table as temporary files.
+ * Temporary files are periodically cleaned. Use the 'file.usage' service to
+ * register the usage of the file which will automatically mark it as permanent.
+ *
+ * @param array $element
+ *   The FAPI element whose values are being saved.
+ * @param \Drupal\Core\Form\FormStateInterface $form_state
+ *   The current state of the form.
+ * @param null|int $delta
+ *   (optional) The delta of the file to return the file entity.
+ *   Defaults to NULL.
+ * @param int $replace
+ *   (optional) The replace behavior when the destination file already exists.
+ *   Possible values include:
+ *   - FILE_EXISTS_REPLACE: Replace the existing file.
+ *   - FILE_EXISTS_RENAME: (default) Append _{incrementing number} until the
+ *     filename is unique.
+ *   - FILE_EXISTS_ERROR: Do nothing and return FALSE.
+ *
+ * @return array|\Drupal\file\FileInterface|null|false
+ *   An array of file entities or a single file entity if $delta != NULL. Each
+ *   array element contains the file entity if the upload succeeded or FALSE if
+ *   there was an error. Function returns NULL if no file was uploaded.
+ */
+function file_save_upload_from_form($element, FormStateInterface $form_state, $delta = NULL, $replace = FILE_EXISTS_RENAME) {
+  $destination = isset($element['#upload_location']) ? $element['#upload_location'] : FALSE;
+  $validators = isset($element['#upload_validators']) ? $element['#upload_validators'] : array();
+  $upload_name = implode('_', $element['#parents']);
+  $errors_before = drupal_get_messages('error');
+
+  $files = file_save_upload($upload_name, $validators, $destination, $delta, $replace);
+
+  // Get all possible new errors that are generated while trying to save the
+  // upload.
+  $new_errors = array_diff(drupal_get_messages('error'), $errors_before);
+
+  if (!empty($new_errors['error'])) {
+    $new_errors = $new_errors['error'];
+
+    if (count($new_errors) > 1) {
+      // Render multiple errors into a single message.
+      $render_array = array(
+        'error' => array(
+          '#markup' => t('One or more files could not be uploaded.'),
+        ),
+        'item_list' => array(
+          '#theme' => 'item_list',
+          '#items' => $new_errors,
+        ),
+      );
+      $error_message = \Drupal::service('renderer')->renderer->renderPlain($render_array);
+    }
+    else {
+      $error_message = reset($new_errors);
+    }
+
+    \Drupal::logger('file')->notice('The file upload failed. %upload', array('%upload' => $upload_name));
+    $form_state->setError($element, $error_message);
+
+    // Empty the old queue and put the errors back as before.
+    drupal_get_messages('error', TRUE);
+    foreach ($errors_before as $error) {
+      drupal_set_message($error, 'error');
+    }
+  }
+  return $files;
+}
+
+/**
  * Saves file uploads to a new location.
  *
+ * @deprecated in Drupal 8.3.0, intended to be removed in Drupal 9.0.0.
+ * This function should not be used during form validation, use
+ * file_save_upload_from_form() instead.
+ *
  * The files will be added to the {file_managed} table as temporary files.
  * Temporary files are periodically cleaned. Use the 'file.usage' service to
  * register the usage of the file which will automatically mark it as permanent.
@@ -1192,9 +1267,7 @@ function file_managed_file_save_upload($element, FormStateInterface $form_state)
   $files_uploaded = $element['#multiple'] && count(array_filter($file_upload)) > 0;
   $files_uploaded |= !$element['#multiple'] && !empty($file_upload);
   if ($files_uploaded) {
-    if (!$files = file_save_upload($upload_name, $element['#upload_validators'], $destination)) {
-      \Drupal::logger('file')->notice('The file upload failed. %upload', array('%upload' => $upload_name));
-      $form_state->setError($element, t('Files in the @name field were unable to be uploaded.', array('@name' => $element['#title'])));
+    if (!$files = file_save_upload_from_form($element, $form_state)) {
       return array();
     }
 
diff --git a/core/modules/locale/src/Form/ImportForm.php b/core/modules/locale/src/Form/ImportForm.php
index 0ea71809bc..60b2d50e74 100644
--- a/core/modules/locale/src/Form/ImportForm.php
+++ b/core/modules/locale/src/Form/ImportForm.php
@@ -108,6 +108,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       ),
       '#size' => 50,
       '#upload_validators' => $validators,
+      '#upload_location' => 'translations://',
       '#attributes' => array('class' => array('file-import-input')),
     );
     $form['langcode'] = array(
@@ -154,7 +155,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-    $this->file = file_save_upload('file', $form['file']['#upload_validators'], 'translations://', 0);
+    $this->file = file_save_upload_from_form($form['file'], $form_state, 0);
 
     // Ensure we have the file uploaded.
     if (!$this->file) {
diff --git a/core/modules/system/src/Form/ThemeSettingsForm.php b/core/modules/system/src/Form/ThemeSettingsForm.php
index 37b5ea1364..e7b11ea730 100644
--- a/core/modules/system/src/Form/ThemeSettingsForm.php
+++ b/core/modules/system/src/Form/ThemeSettingsForm.php
@@ -357,9 +357,10 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     if ($this->moduleHandler->moduleExists('file')) {
       // Handle file uploads.
       $validators = array('file_validate_is_image' => array());
+      $logo_upload_element = $form['logo']['settings']['logo_upload'];
 
       // Check for a new uploaded logo.
-      $file = file_save_upload('logo_upload', $validators, FALSE, 0);
+      $file = file_save_upload_from_form($logo_upload_element, $form_state, 0);
       if (isset($file)) {
         // File upload was attempted.
         if ($file) {
@@ -368,14 +369,14 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
         }
         else {
           // File upload failed.
-          $form_state->setErrorByName('logo_upload', $this->t('The logo could not be uploaded.'));
+          $form_state->setErrorByName($logo_upload_element, $this->t('The logo could not be uploaded.'));
         }
       }
 
       $validators = array('file_validate_extensions' => array('ico png gif jpg jpeg apng svg'));
 
       // Check for a new uploaded favicon.
-      $file = file_save_upload('favicon_upload', $validators, FALSE, 0);
+      $file = file_save_upload_from_form($form['favicon']['settings']['favicon_upload'], $form_state, 0);
       if (isset($file)) {
         // File upload was attempted.
         if ($file) {
