diff --git a/core/modules/user/config/schema/user.schema.yml b/core/modules/user/config/schema/user.schema.yml
index ed7e3875eda929b68150afb01ce08fc3fba7a23a..e768e25558a9c0871f10a8e81d96b72ebd32df4c 100644
--- a/core/modules/user/config/schema/user.schema.yml
+++ b/core/modules/user/config/schema/user.schema.yml
@@ -3,6 +3,8 @@
 user.settings:
   type: config_object
   label: 'User settings'
+  constraints:
+    FullyValidatable: ~
   mapping:
     anonymous:
       type: required_label
@@ -41,12 +43,27 @@ user.settings:
     register:
       type: string
       label: 'Who can register accounts?'
+      # Choices are derived from the constants.
+      # @see \Drupal\user\UserInterface::REGISTER_*
+      # @todo Convert to use Enum in https://www.drupal.org/project/drupal/issues/3450782
+      constraints:
+        Choice:
+          choices:
+            - 'visitors'
+            - 'admin_only'
+            - 'visitors_admin_approval'
     cancel_method:
       type: string
       label: 'When cancelling a user account'
+      constraints:
+        UserCancelMethod: []
     password_reset_timeout:
       type: integer
       label: 'Password reset timeout'
+      # @todo Increase min in https://www.drupal.org/i/3441772
+      constraints:
+        Range:
+          min: 1
     password_strength:
       type: boolean
       label: 'Enable password strength indicator'
diff --git a/core/modules/user/migrations/d6_user_settings.yml b/core/modules/user/migrations/d6_user_settings.yml
index 911682a27803bc8bc9413fe6fe95e84b63bb3e66..8503756bcf1923cb5debd96fb48a299928208f47 100644
--- a/core/modules/user/migrations/d6_user_settings.yml
+++ b/core/modules/user/migrations/d6_user_settings.yml
@@ -16,6 +16,35 @@ process:
   'notify/status_blocked': user_mail_status_blocked_notify
   'notify/status_activated': user_mail_status_activated_notify
   verify_mail: user_email_verification
+  # @see core/modules/user/config/install/user.settings.yml
+  # Default values
+  cancel_method:
+    plugin: default_value
+    default_value: user_cancel_block
+  password_reset_timeout:
+    plugin: default_value
+    default_value: 86400
+  password_strength:
+    plugin: default_value
+    default_value: true
+  'notify/cancel_confirm':
+    plugin: default_value
+    default_value: true
+  'notify/password_reset':
+    plugin: default_value
+    default_value: true
+  'notify/status_canceled':
+    plugin: default_value
+    default_value: false
+  'notify/register_admin_created':
+    plugin: default_value
+    default_value: true
+  'notify/register_no_approval_required':
+    plugin: default_value
+    default_value: true
+  'notify/register_pending_approval':
+    plugin: default_value
+    default_value: true
   register:
     plugin: static_map
     source: user_register
diff --git a/core/modules/user/migrations/d7_user_settings.yml b/core/modules/user/migrations/d7_user_settings.yml
index 8139cdf706c39fa1b827b5a3bd0429e5d29f0779..70c3c2bb1dce2c1bd91d09bf8db8c92901f08402 100644
--- a/core/modules/user/migrations/d7_user_settings.yml
+++ b/core/modules/user/migrations/d7_user_settings.yml
@@ -16,6 +16,35 @@ process:
   'notify/status_blocked': user_mail_status_blocked_notify
   'notify/status_activated': user_mail_status_activated_notify
   verify_mail: user_email_verification
+  # @see core/modules/user/config/install/user.settings.yml
+  # Default values
+  cancel_method:
+    plugin: default_value
+    default_value: user_cancel_block
+  password_reset_timeout:
+    plugin: default_value
+    default_value: 86400
+  password_strength:
+    plugin: default_value
+    default_value: true
+  'notify/cancel_confirm':
+    plugin: default_value
+    default_value: true
+  'notify/password_reset':
+    plugin: default_value
+    default_value: true
+  'notify/status_canceled':
+    plugin: default_value
+    default_value: false
+  'notify/register_admin_created':
+    plugin: default_value
+    default_value: true
+  'notify/register_no_approval_required':
+    plugin: default_value
+    default_value: true
+  'notify/register_pending_approval':
+    plugin: default_value
+    default_value: true
   register:
     plugin: static_map
     source: user_register
diff --git a/core/modules/user/src/Plugin/Validation/Constraint/UserCancelMethodsConstraint.php b/core/modules/user/src/Plugin/Validation/Constraint/UserCancelMethodsConstraint.php
new file mode 100644
index 0000000000000000000000000000000000000000..483c6a8dce1a5a3f934daa89a5d6a04ef0b4d2de
--- /dev/null
+++ b/core/modules/user/src/Plugin/Validation/Constraint/UserCancelMethodsConstraint.php
@@ -0,0 +1,27 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\user\Plugin\Validation\Constraint;
+
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\Core\Validation\Attribute\Constraint;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\Validator\Constraints\Choice;
+
+#[Constraint(
+  id: 'UserCancelMethod',
+  label: new TranslatableMarkup('UserCancelMethod', [], ['context' => 'Validation']),
+)]
+class UserCancelMethodsConstraint implements ContainerFactoryPluginInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): Choice {
+    $configuration['choices'] = array_keys(user_cancel_methods()['#options']);
+    return new Choice($configuration);
+  }
+
+}
diff --git a/core/modules/user/tests/src/Kernel/UserConfigValidationTest.php b/core/modules/user/tests/src/Kernel/UserConfigValidationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..991f13241302d0682d23ceb981a68c11b10850ad
--- /dev/null
+++ b/core/modules/user/tests/src/Kernel/UserConfigValidationTest.php
@@ -0,0 +1,70 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\user\Kernel;
+
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests validating user modules' configuration.
+ *
+ * @group user
+ */
+class UserConfigValidationTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['system', 'user'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+    $this->installConfig('user');
+  }
+
+  /**
+   * Data provider for testUserSettings().
+   *
+   * @return array
+   */
+  public static function providerTestUserSettings(): array {
+    return [
+      "Invalid register" => [
+        'register',
+        'somebody',
+        'The value you selected is not a valid choice.',
+      ],
+      "Invalid cancel_method" => [
+        'cancel_method',
+        'somebody',
+        'The value you selected is not a valid choice.',
+      ],
+      "Invalid password_reset_timeout" => [
+        'password_reset_timeout',
+        '0',
+        'This value should be <em class="placeholder">1</em> or more.',
+      ],
+    ];
+  }
+
+  /**
+   * Tests invalid values in 'user.settings' config properties.
+   *
+   * @dataProvider providerTestUserSettings
+   */
+  public function testUserSettings($property, $property_value, $expected_message): void {
+    $config_name = 'user.settings';
+    $config = $this->config($config_name);
+    $violations = $this->container->get('config.typed')
+      ->createFromNameAndData($config_name, $config->set($property, $property_value)->get())
+      ->validate();
+    $this->assertCount(1, $violations);
+    $this->assertSame($property, $violations[0]->getPropertyPath());
+    $this->assertSame($expected_message, (string) $violations[0]->getMessage());
+  }
+
+}
diff --git a/core/modules/user/tests/src/Kernel/UserMailNotifyTest.php b/core/modules/user/tests/src/Kernel/UserMailNotifyTest.php
index 6205404532014059c31cbca53aa142c1ab18ed8b..3e13061be0a3002f1c796cf9b72f1b116fdf28bc 100644
--- a/core/modules/user/tests/src/Kernel/UserMailNotifyTest.php
+++ b/core/modules/user/tests/src/Kernel/UserMailNotifyTest.php
@@ -103,6 +103,7 @@ public function testUserMailsSent($op, array $mail_keys): void {
    * @dataProvider userMailsProvider
    */
   public function testUserMailsNotSent($op): void {
+    $this->installConfig('user');
     $this->config('user.settings')->set('notify.' . $op, FALSE)->save();
     $return = _user_mail_notify($op, $this->createUser());
     $this->assertNull($return);