diff --git a/lib/SimpleSAML/Store/SQLStore.php b/lib/SimpleSAML/Store/SQLStore.php
index 19df280d792e63d2006bcea2501a660da05532f4..640bbb5dafcb56c2041cb7b27cc696b76bd32e72 100644
--- a/lib/SimpleSAML/Store/SQLStore.php
+++ b/lib/SimpleSAML/Store/SQLStore.php
@@ -95,7 +95,7 @@ class SQLStore implements StoreInterface
         }
 
         while (($row = $fetchTableVersion->fetch(PDO::FETCH_ASSOC)) !== false) {
-            $this->tableVersions[$row['_name']] = (int) $row['_version'];
+            $this->tableVersions[$row['_name']] = intval($row['_version']);
         }
     }
 
@@ -105,74 +105,37 @@ class SQLStore implements StoreInterface
      */
     private function initKVTable(): void
     {
-        $current_version = $this->getTableVersion('kvstore');
+        $tableVer = $this->getTableVersion('kvstore');
+        if ($tableVer === 2) {
+            return;
+        } elseif ($tableVer < 2 && $tableVer > 0) {
+            throw new Exception('No upgrade path available. Please migrate to the latest 1.16+ version of SimpleSAMLphp first before upgrading to 2.x.');
+        }
 
         $text_t = 'TEXT';
-        $time_field = 'TIMESTAMP';
         if ($this->driver === 'mysql') {
             // TEXT data type has size constraints that can be hit at some point, so we use LONGTEXT instead
             $text_t = 'LONGTEXT';
         }
+
+        $time_field = 'TIMESTAMP';
         if ($this->driver === 'sqlsrv') {
             // TIMESTAMP will not work for MSSQL. TIMESTAMP is automatically generated and cannot be inserted
             //    so we use DATETIME instead
             $time_field = 'DATETIME';
         }
 
-        /**
-         * Queries for updates, grouped by version.
-         * New updates can be added as a new array in this array
-         */
-        $table_updates = [
-            [
-                'CREATE TABLE ' . $this->prefix .
-                '_kvstore (_type VARCHAR(30) NOT NULL, _key VARCHAR(50) NOT NULL, _value ' . $text_t .
-                ' NOT NULL, _expire ' . $time_field . ', PRIMARY KEY (_key, _type))',
-                $this->driver === 'sqlite' || $this->driver === 'sqlsrv' || $this->driver === 'pgsql' ?
-                'CREATE INDEX ' . $this->prefix . '_kvstore_expire ON ' . $this->prefix . '_kvstore (_expire)' :
-                'ALTER TABLE ' . $this->prefix . '_kvstore ADD INDEX ' . $this->prefix . '_kvstore_expire (_expire)'
-            ],
-            /**
-             * This upgrade removes the default NOT NULL constraint on the _expire field in MySQL.
-             * Because SQLite does not support field alterations, the approach is to:
-             *     Create a new table without the NOT NULL constraint
-             *     Copy the current data to the new table
-             *     Drop the old table
-             *     Rename the new table correctly
-             *     Read the index
-             */
-            [
-                'CREATE TABLE ' . $this->prefix .
-                '_kvstore_new (_type VARCHAR(30) NOT NULL, _key VARCHAR(50) NOT NULL, _value ' . $text_t .
-                ' NOT NULL, _expire ' . $time_field . ' NULL, PRIMARY KEY (_key, _type))',
-                'INSERT INTO ' . $this->prefix . '_kvstore_new SELECT * FROM ' . $this->prefix . '_kvstore',
-                'DROP TABLE ' . $this->prefix . '_kvstore',
-                // FOR MSSQL use EXEC sp_rename to rename a table (RENAME won't work)
-                $this->driver === 'sqlsrv' ?
-                'EXEC sp_rename ' . $this->prefix . '_kvstore_new, ' . $this->prefix . '_kvstore' :
-                'ALTER TABLE ' . $this->prefix . '_kvstore_new RENAME TO ' . $this->prefix . '_kvstore',
-                $this->driver === 'sqlite' || $this->driver === 'sqlsrv' || $this->driver === 'pgsql' ?
-                'CREATE INDEX ' . $this->prefix . '_kvstore_expire ON ' . $this->prefix . '_kvstore (_expire)' :
-                'ALTER TABLE ' . $this->prefix . '_kvstore ADD INDEX ' . $this->prefix . '_kvstore_expire (_expire)'
-            ]
-        ];
-
-        $latest_version = count($table_updates);
-
-        if ($current_version == $latest_version) {
-            return;
-        }
-
-        // Only run queries for after the current version
-        $updates_to_run = array_slice($table_updates, $current_version);
+        $query = 'CREATE TABLE ' . $this->prefix .
+            '_kvstore (_type VARCHAR(30) NOT NULL, _key VARCHAR(50) NOT NULL, _value ' . $text_t .
+            ' NOT NULL, _expire ' . $time_field . ' NULL, PRIMARY KEY (_key, _type))';
+        $this->pdo->exec($query);
 
-        foreach ($updates_to_run as $version_updates) {
-            foreach ($version_updates as $query) {
-                $this->pdo->exec($query);
-            }
-        }
+        $query = $this->driver === 'sqlite' || $this->driver === 'sqlsrv' || $this->driver === 'pgsql' ?
+            'CREATE INDEX ' . $this->prefix . '_kvstore_expire ON ' . $this->prefix . '_kvstore (_expire)' :
+            'ALTER TABLE ' . $this->prefix . '_kvstore ADD INDEX ' . $this->prefix . '_kvstore_expire (_expire)';
+        $this->pdo->exec($query);
 
-        $this->setTableVersion('kvstore', $latest_version);
+        $this->setTableVersion('kvstore', 2);
     }
 
 
diff --git a/modules/saml/lib/SP/LogoutStore.php b/modules/saml/lib/SP/LogoutStore.php
index c9bea7c808dec29172f7291a8e952ebaca30fb8b..ef6f258e9fef51bf8250a01facbeb74a338c21fe 100644
--- a/modules/saml/lib/SP/LogoutStore.php
+++ b/modules/saml/lib/SP/LogoutStore.php
@@ -32,156 +32,8 @@ class LogoutStore
         $tableVer = $store->getTableVersion('saml_LogoutStore');
         if ($tableVer === 4) {
             return;
-        } elseif ($tableVer === 3) {
-            /**
-             * Table version 4 fixes the column type for the _expire column.
-             * We now use DATETIME instead of TIMESTAMP to support MSSQL.
-             */
-            switch ($store->driver) {
-                case 'pgsql':
-                    // This does not affect the NOT NULL constraint
-                    $update = [
-                        'ALTER TABLE ' . $store->prefix . '_saml_LogoutStore ALTER COLUMN _expire TYPE TIMESTAMP'
-                    ];
-                    break;
-                case 'sqlsrv':
-                    $update = [
-                        'ALTER TABLE ' . $store->prefix . '_saml_LogoutStore ALTER COLUMN _expire DATETIME NOT NULL'
-                    ];
-                    break;
-                case 'sqlite':
-                    /**
-                     * Because SQLite does not support field alterations, the approach is to:
-                     *     Create a new table without the proper column size
-                     *     Copy the current data to the new table
-                     *     Drop the old table
-                     *     Rename the new table correctly
-                     *     Read the index
-                     */
-                    $update = [
-                        'CREATE TABLE ' . $store->prefix . '_saml_LogoutStore_new (' .
-                        '_authSource VARCHAR(255) NOT NULL, _nameId VARCHAR(40) NOT NULL' .
-                        ', _sessionIndex VARCHAR(50) NOT NULL, _expire DATETIME NOT NULL,' .
-                        '_sessionId VARCHAR(50) NOT NULL, UNIQUE (_authSource, _nameID, _sessionIndex))',
-                        'INSERT INTO ' . $store->prefix . '_saml_LogoutStore_new SELECT * FROM ' .
-                        $store->prefix . '_saml_LogoutStore',
-                        'DROP TABLE ' . $store->prefix . '_saml_LogoutStore',
-                        'ALTER TABLE ' . $store->prefix . '_saml_LogoutStore_new RENAME TO ' .
-                        $store->prefix . '_saml_LogoutStore',
-                        'CREATE INDEX ' . $store->prefix . '_saml_LogoutStore_expire ON ' .
-                        $store->prefix . '_saml_LogoutStore (_expire)',
-                        'CREATE INDEX ' . $store->prefix . '_saml_LogoutStore_nameId ON ' .
-                        $store->prefix . '_saml_LogoutStore (_authSource, _nameId)'
-                    ];
-                    break;
-                default:
-                    $update = [
-                        'ALTER TABLE ' . $store->prefix . '_saml_LogoutStore MODIFY _expire DATETIME NOT NULL'
-                    ];
-                    break;
-            }
-
-            try {
-                foreach ($update as $query) {
-                    $store->pdo->exec($query);
-                }
-            } catch (\Exception $e) {
-                Logger::warning('Database error: ' . var_export($store->pdo->errorInfo(), true));
-                return;
-            }
-            $store->setTableVersion('saml_LogoutStore', 4);
-            return;
-        } elseif ($tableVer === 2) {
-            /**
-             * TableVersion 3 fixes the indexes that were set to 255 in version 2;
-             *   they cannot be larger than 191 on MySQL
-             */
-
-            if ($store->driver === 'mysql') {
-                // Drop old indexes
-                $query = 'ALTER TABLE ' . $store->prefix . '_saml_LogoutStore DROP INDEX ' .
-                $store->prefix . '_saml_LogoutStore_nameId';
-                $store->pdo->exec($query);
-                $query = 'ALTER TABLE ' . $store->prefix . '_saml_LogoutStore DROP INDEX _authSource';
-                $store->pdo->exec($query);
-
-                // Create new indexes
-                $query = 'CREATE INDEX ' . $store->prefix . '_saml_LogoutStore_nameId ON ';
-                $query .= $store->prefix . '_saml_LogoutStore (_authSource(191), _nameId)';
-                $store->pdo->exec($query);
-
-                $query = 'ALTER TABLE ' . $store->prefix .
-                '_saml_LogoutStore ADD UNIQUE KEY (_authSource(191), _nameID, _sessionIndex)';
-                $store->pdo->exec($query);
-            }
-
-            $store->setTableVersion('saml_LogoutStore', 3);
-            return;
-        } elseif ($tableVer === 1) {
-            // TableVersion 2 increased the column size to 255 (191 for mysql) which is the maximum length of a FQDN
-            switch ($store->driver) {
-                case 'pgsql':
-                    // This does not affect the NOT NULL constraint
-                    $update = [
-                        'ALTER TABLE ' . $store->prefix .
-                        '_saml_LogoutStore ALTER COLUMN _authSource TYPE VARCHAR(255)'];
-                    break;
-                case 'sqlsrv':
-                    $update = [
-                        'ALTER TABLE ' . $store->prefix .
-                        '_saml_LogoutStore ALTER COLUMN _authSource VARCHAR(255) NOT NULL'
-                    ];
-                    break;
-                case 'sqlite':
-                    /**
-                     * Because SQLite does not support field alterations, the approach is to:
-                     *     Create a new table without the proper column size
-                     *     Copy the current data to the new table
-                     *     Drop the old table
-                     *     Rename the new table correctly
-                     *     Read the index
-                     */
-                    $update = [
-                        'CREATE TABLE ' . $store->prefix .
-                        '_saml_LogoutStore_new (_authSource VARCHAR(255) NOT NULL,' .
-                        '_nameId VARCHAR(40) NOT NULL, _sessionIndex VARCHAR(50) NOT NULL, ' .
-                        '_expire TIMESTAMP NOT NULL, _sessionId VARCHAR(50) NOT NULL, UNIQUE ' .
-                        '(_authSource, _nameID, _sessionIndex))',
-                        'INSERT INTO ' . $store->prefix . '_saml_LogoutStore_new SELECT * FROM ' .
-                        $store->prefix . '_saml_LogoutStore',
-                        'DROP TABLE ' . $store->prefix . '_saml_LogoutStore',
-                        'ALTER TABLE ' . $store->prefix . '_saml_LogoutStore_new RENAME TO ' .
-                        $store->prefix . '_saml_LogoutStore',
-                        'CREATE INDEX ' . $store->prefix . '_saml_LogoutStore_expire ON ' .
-                        $store->prefix . '_saml_LogoutStore (_expire)',
-                        'CREATE INDEX ' . $store->prefix . '_saml_LogoutStore_nameId ON ' .
-                        $store->prefix . '_saml_LogoutStore (_authSource, _nameId)'
-                    ];
-                    break;
-                case 'mysql':
-                    $update = [
-                        'ALTER TABLE ' . $store->prefix .
-                        '_saml_LogoutStore MODIFY _authSource VARCHAR(191) NOT NULL'
-                    ];
-                    break;
-                default:
-                    $update = [
-                        'ALTER TABLE ' . $store->prefix .
-                        '_saml_LogoutStore MODIFY _authSource VARCHAR(255) NOT NULL'
-                    ];
-                    break;
-            }
-
-            try {
-                foreach ($update as $query) {
-                    $store->pdo->exec($query);
-                }
-            } catch (\Exception $e) {
-                Logger::warning('Database error: ' . var_export($store->pdo->errorInfo(), true));
-                return;
-            }
-            $store->setTableVersion('saml_LogoutStore', 2);
-            return;
+        } elseif ($tableVer < 4 && $tableVer > 0) {
+            throw new Exception('No upgrade path available. Please migrate to the latest 1.18+ version of SimpleSAMLphp first before upgrading to 2.x.');
         }
 
         $query = 'CREATE TABLE ' . $store->prefix . '_saml_LogoutStore (