diff --git a/core/modules/aggregator/src/Form/OpmlFeedAdd.php b/core/modules/aggregator/src/Form/OpmlFeedAdd.php
index 93437b1..259b1f0e 100644
--- a/core/modules/aggregator/src/Form/OpmlFeedAdd.php
+++ b/core/modules/aggregator/src/Form/OpmlFeedAdd.php
@@ -115,7 +115,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $validators = array('file_validate_extensions' => array('opml xml'));
-    if ($file = file_save_upload('upload', $validators, FALSE, 0)) {
+    if ($file = file_save_upload('upload', $form_state, $validators, FALSE, 0)) {
       $data = file_get_contents($file->getFileUri());
     }
     else {
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index ee12a41..dbf5f8e 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -654,7 +654,9 @@ function file_cron() {
  * @param $form_field_name
  *   A string that is the associative array key of the upload form element in
  *   the form array.
- * @param $validators
+ * @param \Drupal\Core\Form\FormStateInterface $form_state
+ *   The current state of the form.
+ * @param array $validators
  *   An optional, associative array of callback functions used to validate the
  *   file. See file_validate() for a full discussion of the array format.
  *   If no extension validator is provided it will default to a limited safe
@@ -663,20 +665,20 @@ function file_cron() {
  *   explicitly set the 'file_validate_extensions' validator to an empty array
  *   (Beware: this is not safe and should only be allowed for trusted users, if
  *   at all).
- * @param $destination
+ * @param bool $destination
  *   A string containing the URI that the file should be copied to. This must
  *   be a stream wrapper URI. If this value is omitted, Drupal's temporary
  *   files scheme will be used ("temporary://").
  * @param $delta
  *   Delta of the file to save or NULL to save all files. Defaults to NULL.
- * @param $replace
+ * @param int $replace
  *   Replace behavior when the destination file already exists:
  *   - FILE_EXISTS_REPLACE: Replace the existing file.
  *   - FILE_EXISTS_RENAME: Append _{incrementing number} until the filename is
  *     unique.
  *   - FILE_EXISTS_ERROR: Do nothing and return FALSE.
  *
- * @return
+ * @return mixed
  *   Function returns array of files or a single file object if $delta
  *   != NULL. Each file object contains the file information if the
  *   upload succeeded or FALSE in the event of an error. Function
@@ -689,7 +691,7 @@ function file_cron() {
  *   - source: Path to the file before it is moved.
  *   - destination: Path to the file after it is moved (same as 'uri').
  */
-function file_save_upload($form_field_name, $validators = array(), $destination = FALSE, $delta = NULL, $replace = FILE_EXISTS_RENAME) {
+function file_save_upload($form_field_name, FormStateInterface $form_state, $validators = array(), $destination = FALSE, $delta = NULL, $replace = FILE_EXISTS_RENAME) {
   $user = \Drupal::currentUser();
   static $upload_cache;
 
@@ -723,13 +725,13 @@ function file_save_upload($form_field_name, $validators = array(), $destination
     switch ($file_info->getError()) {
       case UPLOAD_ERR_INI_SIZE:
       case UPLOAD_ERR_FORM_SIZE:
-        drupal_set_message(t('The file %file could not be saved because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $file_info->getFilename(), '%maxsize' => format_size(file_upload_max_size()))), 'error');
+        $form_state->setErrorByName($form_field_name, t('The file %file could not be saved because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $file_info->getFilename(), '%maxsize' => format_size(file_upload_max_size()))));
         $files[$i] = FALSE;
         continue;
 
       case UPLOAD_ERR_PARTIAL:
       case UPLOAD_ERR_NO_FILE:
-        drupal_set_message(t('The file %file could not be saved because the upload did not complete.', array('%file' => $file_info->getFilename())), 'error');
+      $form_state->setErrorByName($form_field_name, t('The file %file could not be saved because the upload did not complete.', array('%file' => $file_info->getFilename())));
         $files[$i] = FALSE;
         continue;
 
@@ -742,7 +744,7 @@ function file_save_upload($form_field_name, $validators = array(), $destination
 
         // Unknown error
       default:
-        drupal_set_message(t('The file %file could not be saved. An unknown error has occurred.', array('%file' => $file_info->getFilename())), 'error');
+        $form_state->setErrorByName($form_field_name, t('The file %file could not be saved. An unknown error has occurred.', array('%file' => $file_info->getFilename())));
         $files[$i] = FALSE;
         continue;
 
@@ -809,7 +811,7 @@ function file_save_upload($form_field_name, $validators = array(), $destination
     // Assert that the destination contains a valid stream.
     $destination_scheme = file_uri_scheme($destination);
     if (!file_stream_wrapper_valid_scheme($destination_scheme)) {
-      drupal_set_message(t('The file could not be uploaded because the destination %destination is invalid.', array('%destination' => $destination)), 'error');
+      $form_state->setErrorByName($form_field_name, t('The file could not be uploaded because the destination %destination is invalid.', array('%destination' => $destination)));
       $files[$i] = FALSE;
       continue;
     }
@@ -823,7 +825,7 @@ function file_save_upload($form_field_name, $validators = array(), $destination
     // If file_destination() returns FALSE then $replace === FILE_EXISTS_ERROR and
     // there's an existing file so we need to bail.
     if ($file->destination === FALSE) {
-      drupal_set_message(t('The file %source could not be uploaded because a file by that name already exists in the destination %directory.', array('%source' => $form_field_name, '%directory' => $destination)), 'error');
+      $form_state->setErrorByName($form_field_name, t('The file %source could not be uploaded because a file by that name already exists in the destination %directory.', array('%source' => $form_field_name, '%directory' => $destination)));
       $files[$i] = FALSE;
       continue;
     }
@@ -847,7 +849,7 @@ function file_save_upload($form_field_name, $validators = array(), $destination
       else {
         $message = SafeMarkup::set($message . ' ' . SafeMarkup::escape(array_pop($errors)));
       }
-      drupal_set_message($message, 'error');
+      $form_state->setErrorByName($form_field_name, $message);
       $files[$i] = FALSE;
       continue;
     }
@@ -857,7 +859,7 @@ function file_save_upload($form_field_name, $validators = array(), $destination
     // operations.
     $file->setFileUri($file->destination);
     if (!drupal_move_uploaded_file($file_info->getRealPath(), $file->getFileUri())) {
-      drupal_set_message(t('File upload error. Could not move uploaded file.'), 'error');
+      $form_state->setErrorByName($form_field_name, t('File upload error. Could not move uploaded file.'));
       \Drupal::logger('file')->notice('Upload error. Could not move uploaded file %file to destination %destination.', array('%file' => $file->getFilename(), '%destination' => $file->getFileUri()));
       $files[$i] = FALSE;
       continue;
@@ -1157,7 +1159,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)) {
+    if (!$files = file_save_upload($upload_name, $form_state, $element['#upload_validators'], $destination)) {
       \Drupal::logger('file')->notice('The file upload failed. %upload', array('%upload' => $upload_name));
       $form_state->setErrorByName($upload_name, t('Files in the !name field were unable to be uploaded.', array('!name' => $element['#title'])));
       return array();
diff --git a/core/modules/file/tests/file_test/src/Form/FileTestForm.php b/core/modules/file/tests/file_test/src/Form/FileTestForm.php
index f903bf0..ea25c85 100644
--- a/core/modules/file/tests/file_test/src/Form/FileTestForm.php
+++ b/core/modules/file/tests/file_test/src/Form/FileTestForm.php
@@ -109,7 +109,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       define('SIMPLETEST_COLLECT_ERRORS', FALSE);
     }
 
-    $file = file_save_upload('file_test_upload', $validators, $destination, 0, $form_state->getValue('file_test_replace'));
+    $file = file_save_upload('file_test_upload', $form_state, $validators, $destination, 0, $form_state->getValue('file_test_replace'));
     if ($file) {
       $form_state->setValue('file_test_upload', $file);
       drupal_set_message(t('File @filepath was uploaded.', array('@filepath' => $file->getFileUri())));
diff --git a/core/modules/locale/src/Form/ImportForm.php b/core/modules/locale/src/Form/ImportForm.php
index ca706ea..6a8ce7c 100644
--- a/core/modules/locale/src/Form/ImportForm.php
+++ b/core/modules/locale/src/Form/ImportForm.php
@@ -159,7 +159,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('file', $form_state, $form['file']['#upload_validators'], 'translations://', 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 fd8b777..637e38a 100644
--- a/core/modules/system/src/Form/ThemeSettingsForm.php
+++ b/core/modules/system/src/Form/ThemeSettingsForm.php
@@ -367,7 +367,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
       $validators = array('file_validate_is_image' => array());
 
       // Check for a new uploaded logo.
-      $file = file_save_upload('logo_upload', $validators, FALSE, 0);
+      $file = file_save_upload('logo_upload', $form_state, $validators, FALSE, 0);
       if (isset($file)) {
         // File upload was attempted.
         if ($file) {
@@ -383,7 +383,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
       $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('favicon_upload', $form_state, $validators, FALSE, 0);
       if (isset($file)) {
         // File upload was attempted.
         if ($file) {
diff --git a/core/modules/update/src/Form/UpdateManagerInstall.php b/core/modules/update/src/Form/UpdateManagerInstall.php
index 43d1f62..7c9bf74 100644
--- a/core/modules/update/src/Form/UpdateManagerInstall.php
+++ b/core/modules/update/src/Form/UpdateManagerInstall.php
@@ -135,7 +135,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     }
     elseif ($_FILES['files']['name']['project_upload']) {
       $validators = array('file_validate_extensions' => array(archiver_get_extensions()));
-      if (!($finfo = file_save_upload('project_upload', $validators, NULL, 0, FILE_EXISTS_REPLACE))) {
+      if (!($finfo = file_save_upload('project_upload', $form_state, $validators, NULL, 0, FILE_EXISTS_REPLACE))) {
         // Failed to upload the file. file_save_upload() calls
         // drupal_set_message() on failure.
         return;
