diff --git a/core/core.services.yml b/core/core.services.yml
index 98ddc9e..062279d 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -893,10 +893,6 @@ services:
     class: Drupal\Core\StreamWrapper\PublicStream
     tags:
       - { name: stream_wrapper, scheme: public }
-  stream_wrapper.private:
-    class: Drupal\Core\StreamWrapper\PrivateStream
-    tags:
-      - { name: stream_wrapper, scheme: private }
   stream_wrapper.temporary:
     class: Drupal\Core\StreamWrapper\TemporaryStream
     tags:
diff --git a/core/includes/file.inc b/core/includes/file.inc
index b38cf14..c5e2673 100644
--- a/core/includes/file.inc
+++ b/core/includes/file.inc
@@ -13,6 +13,7 @@
 use Drupal\Core\Site\Settings;
 use Drupal\Core\StreamWrapper\PublicStream;
 use Drupal\Core\StreamWrapper\StreamWrapperInterface;
+use Drupal\Core\StreamWrapper\PrivateStream;
 
 /**
  * Default mode for new directories. See drupal_chmod().
@@ -436,7 +437,7 @@ function file_prepare_directory(&$directory, $options = FILE_MODIFY_PERMISSIONS)
  */
 function file_ensure_htaccess() {
   file_save_htaccess('public://', FALSE);
-  $private_path = \Drupal::config('system.file')->get('path.private');
+  $private_path = PrivateStream::basePath();
   if (!empty($private_path)) {
     file_save_htaccess('private://', TRUE);
   }
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index 249944f..6bba59a 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -21,7 +21,9 @@
 use Drupal\Core\DependencyInjection\Compiler\RegisterServicesForDestructionPass;
 use Drupal\Core\Plugin\PluginManagerPass;
 use Drupal\Core\Render\MainContent\MainContentRenderersPass;
+use Drupal\Core\Site\Settings;
 use Symfony\Component\DependencyInjection\Compiler\PassConfig;
+use Symfony\Component\DependencyInjection\Definition;
 
 /**
  * ServiceProvider class for mandatory core services.
@@ -44,6 +46,12 @@ public function register(ContainerBuilder $container) {
     $this->registerUuid($container);
     $this->registerTest($container);
 
+    // Only register the private file stream wrapper if a file path has been set.
+    if (Settings::get('file_private_path')) {
+      $container->register('stream_wrapper.private', 'Drupal\Core\StreamWrapper\PrivateStream')
+        ->addTag('stream_wrapper', ['scheme' => 'private']);
+    }
+
     // Add the compiler pass that lets service providers modify existing
     // service definitions. This pass must come first so that later
     // list-building passes are operating on the post-alter services list.
diff --git a/core/lib/Drupal/Core/StreamWrapper/PrivateStream.php b/core/lib/Drupal/Core/StreamWrapper/PrivateStream.php
index 84aa2c1..f85820d 100644
--- a/core/lib/Drupal/Core/StreamWrapper/PrivateStream.php
+++ b/core/lib/Drupal/Core/StreamWrapper/PrivateStream.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\StreamWrapper;
 
 use Drupal\Core\Routing\UrlGeneratorTrait;
+use Drupal\Core\Site\Settings;
 
 /**
  * Drupal private (private://) stream wrapper class.
@@ -41,20 +42,28 @@ public function getDescription() {
   }
 
   /**
-   * Implements Drupal\Core\StreamWrapper\LocalStream::getDirectoryPath()
+   * {@inheritdoc}
    */
   public function getDirectoryPath() {
-    return \Drupal::config('system.file')->get('path.private');
+    return static::basePath();
   }
 
   /**
-   * Implements Drupal\Core\StreamWrapper\StreamWrapperInterface::getExternalUrl().
-   *
-   * @return string
-   *   Returns the HTML URI of a private file.
+   * {@inheritdoc}
    */
-  function getExternalUrl() {
+  public function getExternalUrl() {
     $path = str_replace('\\', '/', $this->getTarget());
     return $this->url('system.private_file_download', ['filepath' => $path], ['absolute' => TRUE]);
   }
+
+  /**
+   * Returns the base path for private://.
+   *
+   * @return string
+   *   The base path for private://.
+   */
+  public static function basePath() {
+    return Settings::get('file_private_path');
+  }
+
 }
diff --git a/core/modules/migrate_drupal/src/Tests/Dump/Drupal6SystemFile.php b/core/modules/migrate_drupal/src/Tests/Dump/Drupal6SystemFile.php
index 91eedf3..cc65200 100644
--- a/core/modules/migrate_drupal/src/Tests/Dump/Drupal6SystemFile.php
+++ b/core/modules/migrate_drupal/src/Tests/Dump/Drupal6SystemFile.php
@@ -22,11 +22,6 @@ public function load() {
       'value',
     ))
     ->values(array(
-      'name' => 'file_directory_path',
-      // This sets up MigrateDrupal6Test to pass. Do not change.
-      'value' => 's:29:"core/modules/simpletest/files";',
-    ))
-    ->values(array(
       'name' => 'file_directory_temp',
       'value' => 's:10:"files/temp";',
     ))
diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateSystemFileTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateSystemFileTest.php
index a100a03..19be586 100644
--- a/core/modules/migrate_drupal/src/Tests/d6/MigrateSystemFileTest.php
+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateSystemFileTest.php
@@ -39,7 +39,6 @@ public function testSystemFile() {
     $old_state = \Drupal::configFactory()->getOverrideState();
     \Drupal::configFactory()->setOverrideState(FALSE);
     $config = \Drupal::config('system.file');
-    $this->assertIdentical($config->get('path.private'), 'core/modules/simpletest/files');
     $this->assertIdentical($config->get('path.temporary'), 'files/temp');
     $this->assertIdentical($config->get('allow_insecure_uploads'), TRUE);
     \Drupal::configFactory()->setOverrideState($old_state);
diff --git a/core/modules/simpletest/src/TestBase.php b/core/modules/simpletest/src/TestBase.php
index 806281e..d414afc 100644
--- a/core/modules/simpletest/src/TestBase.php
+++ b/core/modules/simpletest/src/TestBase.php
@@ -161,6 +161,15 @@
   protected $public_files_directory;
 
   /**
+   * The private file directory for the test environment.
+   *
+   * This is set in TestBase::prepareEnvironment().
+   *
+   * @var string
+   */
+  protected $private_files_directory;
+
+  /**
    * Whether to die in case any test assertion fails.
    *
    * @var boolean
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index 77c725b..1f62ef4 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -794,6 +794,10 @@ protected function setUp() {
       'value' => $this->public_files_directory,
       'required' => TRUE,
     );
+    $settings['settings']['file_private_path'] = (object) array(
+      'value' => $this->private_files_directory,
+      'required' => TRUE,
+    );
     // Save the original site directory path, so that extensions in the
     // site-specific directory can still be discovered in the test site
     // environment.
@@ -874,7 +878,6 @@ protected function setUp() {
     file_prepare_directory($this->private_files_directory, FILE_CREATE_DIRECTORY);
     file_prepare_directory($this->temp_files_directory, FILE_CREATE_DIRECTORY);
     $config->get('system.file')
-      ->set('path.private', $this->private_files_directory)
       ->set('path.temporary', $this->temp_files_directory)
       ->save();
 
diff --git a/core/modules/system/config/install/system.file.yml b/core/modules/system/config/install/system.file.yml
index e9f9df0..ec8c053 100644
--- a/core/modules/system/config/install/system.file.yml
+++ b/core/modules/system/config/install/system.file.yml
@@ -1,6 +1,5 @@
 allow_insecure_uploads: false
 default_scheme: 'public'
 path:
-  private: ''
   temporary: ''
 temporary_maximum_age: 21600
diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml
index 857b7c7..407d83e 100644
--- a/core/modules/system/config/schema/system.schema.yml
+++ b/core/modules/system/config/schema/system.schema.yml
@@ -302,9 +302,6 @@ system.file:
       type: mapping
       label: 'Path settings'
       mapping:
-        private:
-          type: string
-          label: 'Private file system path'
         temporary:
           type: string
           label: 'Temporary directory'
diff --git a/core/modules/system/src/Form/FileSystemForm.php b/core/modules/system/src/Form/FileSystemForm.php
index 7c8db21..b5759f3 100644
--- a/core/modules/system/src/Form/FileSystemForm.php
+++ b/core/modules/system/src/Form/FileSystemForm.php
@@ -11,6 +11,7 @@
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Datetime\DateFormatter;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\StreamWrapper\PrivateStream;
 use Drupal\Core\StreamWrapper\PublicStream;
 use Drupal\Core\Form\ConfigFormBase;
 use Drupal\Core\StreamWrapper\StreamWrapperInterface;
@@ -78,18 +79,15 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $form['file_public_path'] = array(
       '#type' => 'item',
       '#title' => t('Public file system path'),
-      '#default_value' => PublicStream::basePath(),
       '#markup' => PublicStream::basePath(),
       '#description' => t('A local file system path where public files will be stored. This directory must exist and be writable by Drupal. This directory must be relative to the Drupal installation directory and be accessible over the web. This must be changed in settings.php'),
     );
 
     $form['file_private_path'] = array(
-      '#type' => 'textfield',
+      '#type' => 'item',
       '#title' => t('Private file system path'),
-      '#default_value' => $config->get('path.private'),
-      '#maxlength' => 255,
-      '#description' => t('An existing local file system path for storing private files. It should be writable by Drupal and not accessible over the web. See the online handbook for <a href="@handbook">more information about securing private files</a>.', array('@handbook' => 'http://drupal.org/documentation/modules/file')),
-      '#after_build' => array('system_check_directory'),
+      '#markup' => (PrivateStream::basePath() ? PrivateStream::basePath() : t('Not set')),
+      '#description' => t('An existing local file system path for storing private files. It should be writable by Drupal and not accessible over the web. This must be changed in settings.php. See the online handbook for <a href="@handbook">more information about securing private files</a>.', array('@handbook' => 'http://drupal.org/documentation/modules/file')),
     );
 
     $form['file_temporary_path'] = array(
@@ -133,7 +131,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $config = $this->config('system.file')
-      ->set('path.private', $form_state->getValue('file_private_path'))
       ->set('path.temporary', $form_state->getValue('file_temporary_path'))
       ->set('temporary_maximum_age', $form_state->getValue('temporary_maximum_age'));
 
diff --git a/core/modules/system/src/Tests/File/ConfigTest.php b/core/modules/system/src/Tests/File/ConfigTest.php
index cd84905..6a0bd65 100644
--- a/core/modules/system/src/Tests/File/ConfigTest.php
+++ b/core/modules/system/src/Tests/File/ConfigTest.php
@@ -33,7 +33,6 @@ function testFileConfigurationPage() {
     // upon form submission.
     $file_path = $this->public_files_directory;
     $fields = array(
-      'file_private_path' => $file_path . '/file_config_page_test/private',
       'file_temporary_path' => $file_path . '/file_config_page_test/temporary',
       'file_default_scheme' => 'private',
     );
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 5a1c545..31291c4 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -12,6 +12,7 @@
 use Drupal\Core\Database\Database;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Site\Settings;
+use Drupal\Core\StreamWrapper\PrivateStream;
 use Drupal\Core\StreamWrapper\PublicStream;
 
 /**
@@ -360,7 +361,7 @@ function system_requirements($phase) {
       PublicStream::basePath(),
       // By default no private files directory is configured. For private files
       // to be secure the admin needs to provide a path outside the webroot.
-      $filesystem_config->get('path.private'),
+      PrivateStream::basePath(),
       file_directory_temp(),
     );
   }
@@ -377,8 +378,8 @@ function system_requirements($phase) {
       // in the intended site directory, so don't require it.
       $directories[] = conf_path(FALSE) . '/files';
     }
-    if (!empty($GLOBALS['config']['system.file']['path']['private'])) {
-      $directories[] = $GLOBALS['config']['system.file']['path']['private'];
+    if ($file_private_path = Settings::get('file_private_path')) {
+      $directories[] = $file_private_path;
     }
     if (!empty($GLOBALS['config']['system.file']['path']['temporary'])) {
       $directories[] = $GLOBALS['config']['system.file']['path']['temporary'];
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 7b75cc9..dbffb8b 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -14,6 +14,7 @@
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Menu\MenuTreeParameters;
+use Drupal\Core\Site\Settings;
 use Drupal\Core\Url;
 use Drupal\Core\Block\BlockPluginInterface;
 use Drupal\user\UserInterface;
@@ -307,16 +308,6 @@ function system_theme_suggestions_field(array $variables) {
 }
 
 /**
- * Implements hook_stream_wrappers_alter().
- */
-function system_stream_wrappers_alter(&$wrappers) {
-  // Only register the private file stream wrapper if a file path has been set.
-  if (!\Drupal::config('system.file')->get('path.private')) {
-    unset($wrappers['private']);
-  }
-}
-
-/**
  * Menu item access callback - only installed themes can be accessed.
  */
 function _system_themes_access($theme) {
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index 6d5f54f..1404b5b 100644
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -431,6 +431,18 @@
 # $settings['file_public_path'] = 'sites/default/files';
 
 /**
+ * Private file path:
+ *
+ * A local file system path where private files will be stored. This directory
+ * must be absolute and outside of the the Drupal installation directory and
+ * not accessible over the web.
+ *
+ * See http://drupal.org/documentation/modules/file for more information about
+ * securing private files.
+ */
+# $settings['file_private_path'] = '';
+
+/**
  * Session write interval:
  *
  * Set the minimum interval between each session write to database.
