diff --git a/config/install/tfa.settings.yml b/config/install/tfa.settings.yml
index 3e90dce..dcca22d 100644
--- a/config/install/tfa.settings.yml
+++ b/config/install/tfa.settings.yml
@@ -1,5 +1,6 @@
 enabled: 0
 required_roles: { }
+force_setup_when_required: 0
 send_plugins: { }
 login_plugins: { }
 default_validation_plugin: ''
diff --git a/config/schema/tfa.schema.yml b/config/schema/tfa.schema.yml
index 2a5bb33..ef1f7ff 100644
--- a/config/schema/tfa.schema.yml
+++ b/config/schema/tfa.schema.yml
@@ -11,6 +11,9 @@ tfa.settings:
       sequence:
         type: string
         label: 'Role'
+    force_setup_when_required:
+      type: integer
+      label: 'Force required roles to setup when on last validation skip'
     send_plugins:
      type: sequence
      label: 'Enabled send plugins'
diff --git a/src/EventSubscriber/ForceTfaSetup.php b/src/EventSubscriber/ForceTfaSetup.php
new file mode 100644
index 0000000..b5f9736
--- /dev/null
+++ b/src/EventSubscriber/ForceTfaSetup.php
@@ -0,0 +1,136 @@
+<?php
+
+namespace Drupal\tfa\EventSubscriber;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Messenger\MessengerInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Url;
+use Drupal\tfa\TfaValidationPluginManager;
+use Drupal\tfa\TfaLoginPluginManager;
+use Drupal\tfa\TfaContext;
+use Drupal\user\UserDataInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+/**
+ * Event subscriber for enforcing TFA.
+ */
+class ForceTfaSetup implements EventSubscriberInterface {
+
+  /**
+   * The route match.
+   *
+   * @var \Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected $routeMatch;
+
+  /**
+   * The messenger.
+   *
+   * @var \Drupal\Core\Messenger\MessengerInterface
+   */
+  protected $messenger;
+
+  /**
+   * The user account service.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
+  /**
+   * The TFA context.
+   *
+   * @var \Drupal\tfa\TfaContext
+   */
+  protected $tfaContext;
+
+  /**
+   * The force setup enabled status.
+   *
+   * @var bool
+   */
+  protected $enabled;
+
+  /**
+   * Constructs an AutologoutSubscriber object.
+   *
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The route match.
+   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+   *   The messenger.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager service.
+   * @param \Drupal\tfa\TfaValidationPluginManager $tfa_validation_manager
+   *   The plugin manager for TFA validation plugins.
+   * @param \Drupal\tfa\TfaLoginPluginManager $tfa_plugin_manager
+   *   The plugin manager for TFA login plugins.
+   * @param \Drupal\user\UserDataInterface $user_data
+   *   The user data service.
+   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+   *   The request stack.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The configuration service.
+   */
+  public function __construct(RouteMatchInterface $route_match, MessengerInterface $messenger, AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, TfaValidationPluginManager $tfa_validation_manager, TfaLoginPluginManager $tfa_plugin_manager, UserDataInterface $user_data, RequestStack $request_stack, ConfigFactoryInterface $config_factory) {
+    $this->messenger = $messenger;
+    $this->routeMatch = $route_match;
+    $this->currentUser = $current_user;
+    $this->enabled = $config_factory->get('tfa.settings')->get('force_setup_when_required');
+
+    $this->tfaContext = new TfaContext(
+      $tfa_validation_manager,
+      $tfa_plugin_manager,
+      $config_factory,
+      $entity_type_manager->getStorage('user')->load($this->currentUser->id()),
+      $user_data,
+      $request_stack->getCurrentRequest()
+    );
+  }
+
+  /**
+   * Redirect users to TFA overview when no remaining skips.
+   */
+  public function redirect(GetResponseEvent $event) {
+    if (!$this->enabled) {
+      return;
+    }
+
+    $is_tfa_setup_last_chance = $this->tfaContext->isTfaRequired()
+      && $this->tfaContext->isModuleSetup()
+      && !$this->tfaContext->isReady();
+
+    if (!$is_tfa_setup_last_chance || $this->tfaContext->remainingSkips() > 0) {
+      return;
+    }
+
+    if ($is_tfa_setup_last_chance && $this->routeMatch->getRouteName() === 'user.logout') {
+      return;
+    }
+
+    if ($is_tfa_setup_last_chance && strpos($this->routeMatch->getRouteName(), 'tfa.') === 0) {
+      $this->messenger->addError(t('You need to enable Two Factor Authentication now or your account will be blocked.'));
+      return;
+    }
+
+    $tfa_overview_url = Url::fromRoute('tfa.overview', ['user' => $this->currentUser->id()]);
+    $event->setResponse(new RedirectResponse($tfa_overview_url->toString()));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events[KernelEvents::REQUEST][] = ['redirect', 32];
+    return $events;
+  }
+
+}
diff --git a/src/Form/SettingsForm.php b/src/Form/SettingsForm.php
index a38c53d..68152e5 100644
--- a/src/Form/SettingsForm.php
+++ b/src/Form/SettingsForm.php
@@ -172,6 +172,13 @@ class SettingsForm extends ConfigFormBase {
       '#required' => FALSE,
     ];
 
+    $form['force_setup_when_required'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Enable setup enforcement'),
+      '#default_value' => $config->get('force_setup_when_required'),
+      '#description' => $this->t('Redirect the user to setup page when TFA is required and there are no remaining validation skips.'),
+    ];
+
     $form['tfa_allowed_validation_plugins'] = [
       '#type' => 'checkboxes',
       '#title' => $this->t('Allowed Validation plugins'),
@@ -423,6 +430,7 @@ class SettingsForm extends ConfigFormBase {
     $this->config('tfa.settings')
       ->set('enabled', $form_state->getValue('tfa_enabled'))
       ->set('required_roles', $form_state->getValue('tfa_required_roles'))
+      ->set('force_setup_when_required', $form_state->getValue('force_setup_when_required'))
       ->set('send_plugins', array_filter($send_plugins))
       ->set('login_plugins', array_filter($login_plugins))
       ->set('allowed_validation_plugins', array_filter($allowed_validation_plugins))
diff --git a/tests/src/Functional/ForceTfaSetupTest.php b/tests/src/Functional/ForceTfaSetupTest.php
new file mode 100644
index 0000000..3bdb0ee
--- /dev/null
+++ b/tests/src/Functional/ForceTfaSetupTest.php
@@ -0,0 +1,106 @@
+<?php
+
+namespace Drupal\Tests\tfa\Functional;
+
+/**
+ * Tests for the tfa setup enforcement.
+ *
+ * @group Tfa
+ */
+class ForceTfaSetupTest extends TfaTestBase {
+
+  /**
+   * User doing the TFA Validation.
+   *
+   * @var \Drupal\user\Entity\User
+   */
+  protected $webUser;
+
+  /**
+   * Administrator to handle configurations.
+   *
+   * @var \Drupal\user\Entity\User
+   */
+  protected $adminUser;
+
+  /**
+   * TFA settings.
+   *
+   * @var \Drupal\Core\Config\Config
+   */
+  protected $config;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() : void {
+    parent::setUp();
+    $this->webUser = $this->drupalCreateUser(['setup own tfa']);
+    $this->adminUser = $this->drupalCreateUser(['admin tfa settings']);
+    $this->config = $this->config('tfa.settings');
+
+    $this->config->set('validation_skip', 2)
+      ->set('enabled', 1)
+      ->set('force_setup_when_required', 1)
+      ->set('default_validation_plugin', 'tfa_recovery_code')
+      ->set('allowed_validation_plugins', ['tfa_recovery_code' => 'tfa_recovery_code'])
+      ->set('encryption', $this->encryptionProfile->id())
+      ->save();
+  }
+
+  /**
+   * Tests the tfa login process.
+   */
+  public function testTfaLogin() {
+    $assert_session = $this->assertSession();
+
+    $this->drupalLogin($this->webUser);
+    $this->assertUrl('user/' . $this->webUser->id());
+
+    // Setup enforcement is not active when the user roles
+    // are not required.
+    $this->drupalLogout();
+    $this->drupalLogin($this->webUser);
+    $this->assertUrl('user/' . $this->webUser->id());
+
+    // Make it required.
+    $web_user_roles = $this->webUser->getRoles(TRUE);
+    $this->config->set('required_roles', [$web_user_roles[0] => $web_user_roles[0]])
+      ->save();
+
+    $this->drupalLogout();
+    $this->drupalLogin($this->webUser);
+    $this->assertUrl('user/' . $this->webUser->id());
+
+    // The User is redirected to the setup page.
+    $this->drupalLogout();
+    $this->drupalLogin($this->webUser);
+    $this->assertUrl('/user/' . $this->webUser->id() . '/security/tfa');
+
+    $this->drupalGet('<front>');
+    $this->assertUrl('/user/' . $this->webUser->id() . '/security/tfa');
+
+    $this->config->set('force_setup_when_required', 0)->save();
+    $this->drupalGet('user/' . $this->webUser->id());
+    $this->assertUrl('user/' . $this->webUser->id());
+
+    $this->config->set('force_setup_when_required', 1)->save();
+
+    $this->drupalGet('user/' . $this->webUser->id());
+    $this->assertUrl('/user/' . $this->webUser->id() . '/security/tfa');
+
+    $this->clickLink('Generate codes');
+    $assert_session->statusCodeEquals(200);
+    $assert_session->pageTextContains('Enter your current password to continue.');
+    $edit = [
+      'current_pass' => $this->webUser->passRaw,
+    ];
+    $this->submitForm($edit, 'Confirm');
+    $this->submitForm([], 'Save codes to account');
+
+    // Other pages can be visited now.
+    $this->drupalGet('user/' . $this->webUser->id());
+    $this->assertUrl('user/' . $this->webUser->id());
+  }
+
+}
diff --git a/tfa.services.yml b/tfa.services.yml
index 44ae361..1a5c775 100644
--- a/tfa.services.yml
+++ b/tfa.services.yml
@@ -17,4 +17,9 @@ services:
   tfa.route_subscriber:
     class: Drupal\tfa\Routing\TfaRouteSubscriber
     tags:
-      - { name: event_subscriber }
\ No newline at end of file
+      - { name: event_subscriber }
+  tfa.force_setup:
+    class: Drupal\tfa\EventSubscriber\ForceTfaSetup
+    arguments: ['@current_route_match', '@messenger', '@current_user', '@entity_type.manager', '@plugin.manager.tfa.validation', '@plugin.manager.tfa.login', '@user.data', '@request_stack', '@config.factory']
+    tags:
+      - { name: event_subscriber }
