diff --git a/file_entity.module b/file_entity.module
index 939d803..75b3666 100644
--- a/file_entity.module
+++ b/file_entity.module
@@ -92,6 +92,44 @@ function file_entity_action_info_alter(&$actions) {
 }
 
 /**
+ * Implements hook_field_info_alter().
+ */
+function file_entity_field_info_alter(&$info) {
+  if (isset($info['file'])) {
+    $info['file']['class'] = '\Drupal\file_entity\Plugin\Field\FieldType\FileEntityItem';
+  }
+}
+
+/**
+ * Checks that the filename ends with an allowed extension.
+ *
+ * @param \Drupal\file\FileInterface $file
+ *   A file entity.
+ * @param string $extensions
+ *   A string with a space separated list of allowed extensions.
+ *
+ * @return array
+ *   An empty array if the file extension is allowed or an array containing an
+ *   error message if it's not.
+ *
+ * @see hook_file_validate()
+ */
+function file_entity_validate_extensions(FileInterface $file, $extensions) {
+  $errors = [];
+
+  // The filename of a newly created file will contain the extension, whereas
+  // the file URI will be a temporary filename, without the extension, until it
+  // has been saved. Once saved, the file name may no longer match the file URI,
+  // which will contain the actual file extension.
+  $compare = $file->isNew() ? $file->getFilename() : $file->getFileUri();
+  $regex = '/\.(' . preg_replace('/ +/', '|', preg_quote($extensions)) . ')$/i';
+  if (!preg_match($regex, $compare)) {
+    $errors[] = t('Only files with the following extensions are allowed: %files-allowed.', ['%files-allowed' => $extensions]);
+  }
+  return $errors;
+}
+
+/**
  * Implements hook_field_formatter_info_alter().
  */
 function file_entity_field_formatter_info_alter(array &$info) {
diff --git a/src/Form/FileEditForm.php b/src/Form/FileEditForm.php
index b0eb94b..0d96199 100644
--- a/src/Form/FileEditForm.php
+++ b/src/Form/FileEditForm.php
@@ -52,7 +52,7 @@ public function form(array $form, FormStateInterface $form_state) {
         // Set up replacement file validation.
         $replacement_options = array();
         // Replacement file must have the same extension as the original file.
-        $replacement_options['file_extensions'] = pathinfo($file->getFilename(), PATHINFO_EXTENSION);
+        $replacement_options['file_extensions'] = pathinfo($file->getFileUri(), PATHINFO_EXTENSION);
 
         $form['replace_upload'] = array(
           '#type' => 'managed_file',
@@ -60,10 +60,16 @@ public function form(array $form, FormStateInterface $form_state) {
           '#upload_validators' => $this->getUploadValidators($replacement_options),
         );
 
+        // Replace options given for core extension validation handler, so that
+        // the correct extensions will be listed in the file upload help.
+        $upload_validators = $form['replace_upload']['#upload_validators'];
+        if (isset($upload_validators['file_entity_validate_extensions'])) {
+          $upload_validators['file_validate_extensions'] = $upload_validators['file_entity_validate_extensions'];
+        }
         $file_upload_help = array(
           '#theme' => 'file_upload_help',
           '#description' => $this->t('This file will replace the existing file. This action cannot be undone.'),
-          '#upload_validators' => $form['replace_upload']['#upload_validators'],
+          '#upload_validators' => $upload_validators,
         );
         $form['replace_upload']['#description'] = drupal_render($file_upload_help);
       }
diff --git a/src/Plugin/Field/FieldType/FileEntityItem.php b/src/Plugin/Field/FieldType/FileEntityItem.php
new file mode 100644
index 0000000..4ed9c0f
--- /dev/null
+++ b/src/Plugin/Field/FieldType/FileEntityItem.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\file_entity\Plugin\Field\FieldType;
+
+use Drupal\file\Plugin\Field\FieldType\FileItem;
+
+/**
+ * Replacement for the core file field type class.
+ */
+class FileEntityItem extends FileItem {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getUploadValidators() {
+    $validators = parent::getUploadValidators();
+
+    if (isset($validators['file_validate_extensions'])) {
+      $validators['file_entity_validate_extensions'] = $validators['file_validate_extensions'];
+      unset($validators['file_validate_extensions']);
+    }
+
+    return $validators;
+  }
+
+}
diff --git a/src/UploadValidatorsTrait.php b/src/UploadValidatorsTrait.php
index 6646739..e2f6215 100644
--- a/src/UploadValidatorsTrait.php
+++ b/src/UploadValidatorsTrait.php
@@ -26,7 +26,10 @@ public function getUploadValidators(array $options = array()) {
     // Validate file extensions. If there are no file extensions in $params and
     // there are no Media defaults, there is no file extension validation.
     if (!empty($options['file_extensions'])) {
-      $validators['file_validate_extensions'] = array($options['file_extensions']);
+      $validators['file_entity_validate_extensions'] = array($options['file_extensions']);
+      // Set core extension validation handler, so that its default extension
+      // validation does not run as well as file_entity_validate_extensions().
+      $validators['file_validate_extensions'] = array();
     }
 
     // Cap the upload size according to the system or user defined limit.
