diff --git a/core/modules/system/src/Form/ThemeSettingsForm.php b/core/modules/system/src/Form/ThemeSettingsForm.php
index f5cfb09082..2ad98931a3 100644
--- a/core/modules/system/src/Form/ThemeSettingsForm.php
+++ b/core/modules/system/src/Form/ThemeSettingsForm.php
@@ -324,9 +324,21 @@ public function buildForm(array $form, FormStateInterface $form_state, $theme =
       // Process the theme and all its base themes.
       foreach ($theme_keys as $theme) {
         // Include the theme-settings.php file.
-        $filename = DRUPAL_ROOT . '/' . $themes[$theme]->getPath() . '/theme-settings.php';
-        if (file_exists($filename)) {
-          require_once $filename;
+        $theme_path = drupal_get_path('theme', $theme);
+        $theme_settings_file = $theme_path . '/theme-settings.php';
+        $theme_file = $theme_path . '/' . $theme . '.theme';
+        $filenames = [$theme_settings_file, $theme_file];
+        foreach ($filenames as $filename) {
+          if (file_exists($filename)) {
+            require_once $filename;
+
+            // The file must be required for the cached form too.
+            $files = $form_state->getBuildInfo()['files'];
+            if (!in_array($filename, $files)) {
+              $files[] = $filename;
+            }
+            $form_state->addBuildInfo('files', $files);
+          }
         }
 
         // Call theme-specific settings.
diff --git a/core/modules/system/tests/src/FunctionalJavascript/ThemeFormSettingsTest.php b/core/modules/system/tests/src/FunctionalJavascript/ThemeFormSettingsTest.php
new file mode 100644
index 0000000000..8e4729fe33
--- /dev/null
+++ b/core/modules/system/tests/src/FunctionalJavascript/ThemeFormSettingsTest.php
@@ -0,0 +1,78 @@
+<?php
+
+namespace Drupal\Tests\system\FunctionalJavascript;
+
+use Drupal\file\Entity\File;
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+use Drupal\Tests\TestFileCreationTrait;
+
+/**
+ * Tests that theme form settings works correctly.
+ *
+ * @group system
+ */
+class ThemeFormSettingsTest extends JavascriptTestBase {
+
+  use TestFileCreationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['file'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $admin = $this->drupalCreateUser(['administer themes']);
+    $this->drupalLogin($admin);
+  }
+
+  /**
+   * Tests that submission handler works correctly.
+   *
+   * @dataProvider providerTestFormSettingsSubmissionHandler
+   */
+  public function testFormSettingsSubmissionHandler($theme) {
+
+    \Drupal::service('theme_handler')->install([$theme]);
+
+    $page = $this->getSession()->getPage();
+    $assert_session = $this->assertSession();
+
+    $this->drupalGet("admin/appearance/settings/$theme");
+
+    // Add a new managed file.
+    $file = current($this->getTestFiles('image'));
+    $image_file_path = \Drupal::service('file_system')->realpath($file->uri);
+    $page->attachFileToField('files[custom_logo]', $image_file_path);
+    $assert_session->waitForButton('custom_logo_remove_button');
+
+    // Assert the new file is uploaded as temporary. This file should not be
+    // saved as permanent if settings are not submited.
+    $image_field = $this->xpath('//input[@name="custom_logo[fids]"]')[0];
+    $file = File::load($image_field->getValue());
+    $this->assertFalse($file->isPermanent());
+
+    $page->pressButton('Save configuration');
+    \Drupal::entityTypeManager()->getStorage('file')->resetCache();
+
+    // Assert the uploaded file is saved as permanent.
+    $image_field = $this->xpath('//input[@name="custom_logo[fids]"]')[0];
+    $file = File::load($image_field->getValue());
+    $this->assertTrue($file->isPermanent());
+  }
+
+  /**
+   * Provides test data for ::testFormSettingsSubmissionHandler().
+   */
+  public function providerTestFormSettingsSubmissionHandler() {
+    return [
+      'test theme.theme' => ['test_theme_theme'],
+      'test theme-settings.php' => ['test_theme_settings'],
+    ];
+  }
+
+}
diff --git a/core/modules/system/tests/themes/test_theme_settings/config/schema/test_theme_settings.schema.yml b/core/modules/system/tests/themes/test_theme_settings/config/schema/test_theme_settings.schema.yml
new file mode 100644
index 0000000000..a53e94a0c5
--- /dev/null
+++ b/core/modules/system/tests/themes/test_theme_settings/config/schema/test_theme_settings.schema.yml
@@ -0,0 +1,12 @@
+# Schema for the configuration files of the Test theme settings.
+
+test_theme_settings.settings:
+  type: theme_settings
+  label: 'Test theme settings'
+  mapping:
+    custom_logo:
+      type: sequence
+      label: 'Custom logo'
+      sequence:
+        type: integer
+        label: 'fids'
diff --git a/core/modules/system/tests/themes/test_theme_settings/test_theme_settings.info.yml b/core/modules/system/tests/themes/test_theme_settings/test_theme_settings.info.yml
new file mode 100644
index 0000000000..38dd300e71
--- /dev/null
+++ b/core/modules/system/tests/themes/test_theme_settings/test_theme_settings.info.yml
@@ -0,0 +1,6 @@
+name: 'Theme test theme-settings.php'
+type: theme
+description: 'Test theme that extends theme settings options via theme-settings.php file'
+version: VERSION
+core: 8.x
+base theme: false
diff --git a/core/modules/system/tests/themes/test_theme_settings/theme-settings.php b/core/modules/system/tests/themes/test_theme_settings/theme-settings.php
new file mode 100644
index 0000000000..7f3c1395f9
--- /dev/null
+++ b/core/modules/system/tests/themes/test_theme_settings/theme-settings.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Test to ensure theme compatibility with managed files.
+ */
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\file\Entity\File;
+
+/**
+ * Implements hook_form_system_theme_settings_alter().
+ */
+function test_theme_settings_form_system_theme_settings_alter(&$form, FormStateInterface $form_state) {
+  $form['custom_logo'] = [
+    '#type' => 'managed_file',
+    '#title' => t('Secondary logo.'),
+    '#default_value' => theme_get_setting('custom_logo'),
+    '#progress_indicator' => 'bar',
+    '#progress_message'   => t('Please wait...'),
+    '#upload_location' => 'public://test',
+    '#upload_validators'  => [
+      'file_validate_extensions' => ['gif png jpg jpeg'],
+    ],
+  ];
+
+  $form['#submit'][] = 'test_theme_settings_form_system_theme_settings_submit';
+}
+
+/**
+ * Test theme form settings submission handler.
+ */
+function test_theme_settings_form_system_theme_settings_submit(&$form, FormStateInterface $form_state) {
+  if ($file_id = $form_state->getValue(['custom_logo', '0'])) {
+    $file = File::load($file_id);
+    $file->setPermanent();
+    $file->save();
+  }
+}
diff --git a/core/modules/system/tests/themes/test_theme_theme/config/schema/test_theme_theme.schema.yml b/core/modules/system/tests/themes/test_theme_theme/config/schema/test_theme_theme.schema.yml
new file mode 100644
index 0000000000..fcd044edd7
--- /dev/null
+++ b/core/modules/system/tests/themes/test_theme_theme/config/schema/test_theme_theme.schema.yml
@@ -0,0 +1,12 @@
+# Schema for the configuration files of the Test theme theme.
+
+test_theme_theme.settings:
+  type: theme_settings
+  label: 'Test theme settings'
+  mapping:
+    custom_logo:
+      type: sequence
+      label: 'Custom logo'
+      sequence:
+        type: integer
+        label: 'fids'
diff --git a/core/modules/system/tests/themes/test_theme_theme/test_theme_theme.info.yml b/core/modules/system/tests/themes/test_theme_theme/test_theme_theme.info.yml
new file mode 100644
index 0000000000..c67a4be2c5
--- /dev/null
+++ b/core/modules/system/tests/themes/test_theme_theme/test_theme_theme.info.yml
@@ -0,0 +1,6 @@
+name: 'Theme test theme.theme file'
+type: theme
+description: 'Test theme that extends theme settings options via theme.theme file'
+version: VERSION
+core: 8.x
+base theme: false
diff --git a/core/modules/system/tests/themes/test_theme_theme/test_theme_theme.theme b/core/modules/system/tests/themes/test_theme_theme/test_theme_theme.theme
new file mode 100644
index 0000000000..937494f101
--- /dev/null
+++ b/core/modules/system/tests/themes/test_theme_theme/test_theme_theme.theme
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Test to ensure theme compatibility with managed files.
+ */
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\file\Entity\File;
+
+/**
+ * Implements hook_form_system_theme_settings_alter().
+ */
+function test_theme_theme_form_system_theme_settings_alter(&$form, FormStateInterface $form_state) {
+
+  $form['custom_logo'] = [
+    '#type' => 'managed_file',
+    '#title' => t('Secondary logo.'),
+    '#default_value' => theme_get_setting('custom_logo'),
+    '#progress_indicator' => 'bar',
+    '#progress_message'   => t('Please wait...'),
+    '#upload_location' => 'public://test',
+    '#upload_validators'  => [
+      'file_validate_extensions' => ['gif png jpg jpeg'],
+    ],
+  ];
+
+  $form['#submit'][] = 'test_theme_theme_form_system_theme_settings_submit';
+}
+
+/**
+ * Test theme form settings submission handler.
+ */
+function test_theme_theme_form_system_theme_settings_submit(&$form, FormStateInterface $form_state) {
+  if ($file_id = $form_state->getValue(['custom_logo', '0'])) {
+    $file = File::load($file_id);
+    $file->setPermanent();
+    $file->save();
+  }
+}
