diff --git a/lib/private/Updater.php b/lib/private/Updater.php
index a66d49941cd88d8ac24213bec2298b9af8f8073a..3f4e54cf803ad007e7b40ecc0ebcf0dbe5dc5122 100644
--- a/lib/private/Updater.php
+++ b/lib/private/Updater.php
@@ -157,9 +157,9 @@ class Updater extends BasicEmitter {
 	/**
 	 * Return version from which this version is allowed to upgrade from
 	 *
-	 * @return string allowed previous version
+	 * @return array allowed previous versions per vendor
 	 */
-	private function getAllowedPreviousVersion() {
+	private function getAllowedPreviousVersions() {
 		// this should really be a JSON file
 		require \OC::$SERVERROOT . '/version.php';
 		/** @var array $OC_VersionCanBeUpgradedFrom */
@@ -182,26 +182,22 @@ class Updater extends BasicEmitter {
 	 * Whether an upgrade to a specified version is possible
 	 * @param string $oldVersion
 	 * @param string $newVersion
-	 * @param string $allowedPreviousVersion
+	 * @param array $allowedPreviousVersions
 	 * @return bool
 	 */
-	public function isUpgradePossible($oldVersion, $newVersion, $allowedPreviousVersion) {
-		$allowedUpgrade = (version_compare($allowedPreviousVersion, $oldVersion, '<=')
-			&& (version_compare($oldVersion, $newVersion, '<=') || $this->config->getSystemValue('debug', false)));
-
-		if ($allowedUpgrade) {
-			return $allowedUpgrade;
+	public function isUpgradePossible($oldVersion, $newVersion, array $allowedPreviousVersions) {
+		$version = explode('.', $oldVersion);
+		$majorMinor = $version[0] . '.' . $version[1];
+
+		$currentVendor = $this->config->getAppValue('core', 'vendor', '');
+		if ($currentVendor === 'nextcloud') {
+			return isset($allowedPreviousVersions[$currentVendor][$majorMinor])
+				&& (version_compare($oldVersion, $newVersion, '<=') ||
+					$this->config->getSystemValue('debug', false));
 		}
 
-		// Upgrade not allowed, someone switching vendor?
-		if ($this->getVendor() !== $this->config->getAppValue('core', 'vendor', '')) {
-			$oldVersion = explode('.', $oldVersion);
-			$newVersion = explode('.', $newVersion);
-
-			return $oldVersion[0] === $newVersion[0] && $oldVersion[1] === $newVersion[1];
-		}
-
-		return false;
+		// Check if the instance can be migrated
+		return isset($allowedPreviousVersions[$currentVendor][$majorMinor]);
 	}
 
 	/**
@@ -215,8 +211,8 @@ class Updater extends BasicEmitter {
 	 */
 	private function doUpgrade($currentVersion, $installedVersion) {
 		// Stop update if the update is over several major versions
-		$allowedPreviousVersion = $this->getAllowedPreviousVersion();
-		if (!self::isUpgradePossible($installedVersion, $currentVersion, $allowedPreviousVersion)) {
+		$allowedPreviousVersions = $this->getAllowedPreviousVersions();
+		if (!$this->isUpgradePossible($installedVersion, $currentVersion, $allowedPreviousVersions)) {
 			throw new \Exception('Updates between multiple major versions and downgrades are unsupported.');
 		}
 
diff --git a/tests/lib/UpdaterTest.php b/tests/lib/UpdaterTest.php
index 80c7c28cd6841023db40653c6933f99fd4fd41e8..afa0635768d5bdfa6eb8bd8f82720e36fec2d3ff 100644
--- a/tests/lib/UpdaterTest.php
+++ b/tests/lib/UpdaterTest.php
@@ -56,93 +56,32 @@ class UpdaterTest extends TestCase {
 		);
 	}
 
-	/**
-	 * @param string $baseUrl
-	 * @return string
-	 */
-	private function buildUpdateUrl($baseUrl) {
-		return $baseUrl . '?version='.implode('x', \OCP\Util::getVersion()).'xinstalledatxlastupdatedatx'.\OC_Util::getChannel().'xx';
-	}
-
 	/**
 	 * @return array
 	 */
 	public function versionCompatibilityTestData() {
 		return [
-			['1', '2', '1', true],
-			['2', '2', '2', true],
-			['6.0.5.0', '6.0.6.0', '5.0', true],
-			['5.0.6.0', '7.0.4.0', '6.0', false],
-			// allow upgrading within the same major release
-			['8.0.0.0', '8.0.0.0', '8.0', true],
-			['8.0.0.0', '8.0.0.4', '8.0', true],
-			['8.0.0.0', '8.0.1.0', '8.0', true],
-			['8.0.0.0', '8.0.2.0', '8.0', true],
-			// does not allow downgrading within the same major release
-			['8.0.1.0', '8.0.0.0', '8.0', false],
-			['8.0.2.0', '8.0.1.0', '8.0', false],
-			['8.0.0.4', '8.0.0.0', '8.0', false],
-			// allows upgrading within the patch version
-			['8.0.0.0', '8.0.0.1', '8.0', true],
-			['8.0.0.0', '8.0.0.2', '8.0', true],
-			// does not allow downgrading within the same major release
-			['8.0.0.1', '8.0.0.0', '8.0', false],
-			['8.0.0.2', '8.0.0.0', '8.0', false],
-			// allow upgrading to the next major release
-			['8.0.0.0', '8.1.0.0', '8.0', true],
-			['8.0.0.0', '8.1.1.0', '8.0', true],
-			['8.0.0.0', '8.1.1.5', '8.0', true],
-			['8.0.0.2', '8.1.1.5', '8.0', true],
-			['8.1.0.0', '8.2.0.0', '8.1', true],
-			['8.1.0.2', '8.2.0.4', '8.1', true],
-			['8.1.0.5', '8.2.0.1', '8.1', true],
-			['8.1.0.0', '8.2.1.0', '8.1', true],
-			['8.1.0.2', '8.2.1.5', '8.1', true],
-			['8.1.0.5', '8.2.1.1', '8.1', true],
-			// does not allow downgrading to the previous major release
-			['8.1.0.0', '8.0.0.0', '7.0', false],
-			['8.1.1.0', '8.0.0.0', '7.0', false],
-			// does not allow skipping major releases
-			['8.0.0.0', '8.2.0.0', '8.1', false],
-			['8.0.0.0', '8.2.1.0', '8.1', false],
-			['8.0.0.0', '9.0.1.0', '8.2', false],
-			['8.0.0.0', '10.0.0.0', '9.3', false],
-			// allows updating to the next major release
-			['8.2.0.0', '9.0.0.0', '8.2', true],
-			['8.2.0.0', '9.0.0.0', '8.2', true],
-			['8.2.0.0', '9.0.1.0', '8.2', true],
-			['8.2.0.0', '9.0.1.1', '8.2', true],
-			['8.2.0.2', '9.0.1.1', '8.2', true],
-			['8.2.2.0', '9.0.1.0', '8.2', true],
-			['8.2.2.2', '9.0.1.1', '8.2', true],
-			['9.0.0.0', '9.1.0.0', '9.0', true],
-			['9.0.0.0', '9.1.0.2', '9.0', true],
-			['9.0.0.2', '9.1.0.1', '9.0', true],
-			['9.1.0.0', '9.2.0.0', '9.1', true],
-			['9.2.0.0', '9.3.0.0', '9.2', true],
-			['9.3.0.0', '10.0.0.0', '9.3', true],
-			// does not allow updating to the next major release (first number)
-			['9.0.0.0', '8.2.0.0', '8.1', false],
-			// other cases
-			['8.0.0.0', '8.1.5.0', '8.0', true],
-			['8.2.0.0', '9.0.0.0', '8.2', true],
-			['8.2.0.0', '9.1.0.0', '9.0', false],
-			['9.0.0.0', '8.1.0.0', '8.0', false],
-			['9.0.0.0', '8.0.0.0', '7.0', false],
-			['9.1.0.0', '8.0.0.0', '7.0', false],
-			['8.2.0.0', '8.1.0.0', '8.0', false],
-
-			// With debug enabled
-			['8.0.0.0', '8.2.0.0', '8.1', false, true],
-			['8.1.0.0', '8.2.0.0', '8.1', true, true],
-			['8.2.0.1', '8.2.0.1', '8.1', true, true],
-			['8.3.0.0', '8.2.0.0', '8.1', true, true],
+			// Upgrade with invalid version
+			['9.1.1.13', '11.0.2.25', ['nextcloud' => ['11.0' => true]], false],
+			['10.0.1.13', '11.0.2.25', ['nextcloud' => ['11.0' => true]], false],
+			// Upgrad with valid version
+			['11.0.1.13', '11.0.2.25', ['nextcloud' => ['11.0' => true]], true],
+			// Downgrade with valid version
+			['11.0.2.25', '11.0.1.13', ['nextcloud' => ['11.0' => true]], false],
+			['11.0.2.25', '11.0.1.13', ['nextcloud' => ['11.0' => true]], true, true],
+			// Downgrade with invalid version
+			['11.0.2.25', '10.0.1.13', ['nextcloud' => ['10.0' => true]], false],
+			['11.0.2.25', '10.0.1.13', ['nextcloud' => ['10.0' => true]], false, true],
 
-			// Downgrade of maintenance
-			['9.0.53.0', '9.0.4.0', '8.1', false, false, 'nextcloud'],
-			// with vendor switch
-			['9.0.53.0', '9.0.4.0', '8.1', true, false, ''],
-			['9.0.53.0', '9.0.4.0', '8.1', true, false, 'owncloud'],
+			// Migration with unknown vendor
+			['9.1.1.13', '11.0.2.25', ['nextcloud' => ['9.1' => true]], false, false, 'owncloud'],
+			['9.1.1.13', '11.0.2.25', ['nextcloud' => ['9.1' => true]], false, true, 'owncloud'],
+			// Migration with unsupported vendor version
+			['9.1.1.13', '11.0.2.25', ['owncloud' => ['10.0' => true]], false, false, 'owncloud'],
+			['9.1.1.13', '11.0.2.25', ['owncloud' => ['10.0' => true]], false, true, 'owncloud'],
+			// Migration with valid vendor version
+			['9.1.1.13', '11.0.2.25', ['owncloud' => ['9.1' => true]], true, false, 'owncloud'],
+			['9.1.1.13', '11.0.2.25', ['owncloud' => ['9.1' => true]], true, true, 'owncloud'],
 		];
 	}
 
@@ -151,12 +90,12 @@ class UpdaterTest extends TestCase {
 	 *
 	 * @param string $oldVersion
 	 * @param string $newVersion
-	 * @param string $allowedVersion
+	 * @param array $allowedVersions
 	 * @param bool $result
 	 * @param bool $debug
 	 * @param string $vendor
 	 */
-	public function testIsUpgradePossible($oldVersion, $newVersion, $allowedVersion, $result, $debug = false, $vendor = 'nextcloud') {
+	public function testIsUpgradePossible($oldVersion, $newVersion, $allowedVersions, $result, $debug = false, $vendor = 'nextcloud') {
 		$this->config->expects($this->any())
 			->method('getSystemValue')
 			->with('debug', false)
@@ -166,7 +105,7 @@ class UpdaterTest extends TestCase {
 			->with('core', 'vendor', '')
 			->willReturn($vendor);
 
-		$this->assertSame($result, $this->updater->isUpgradePossible($oldVersion, $newVersion, $allowedVersion));
+		$this->assertSame($result, $this->updater->isUpgradePossible($oldVersion, $newVersion, $allowedVersions));
 	}
 
 	public function testSetSkip3rdPartyAppsDisable() {
diff --git a/version.php b/version.php
index 90f4e65055aa7b4dab2858605dae653d05c83185..3d8abb5f2f43dc7eaff23c126cee09083d26f9f2 100644
--- a/version.php
+++ b/version.php
@@ -31,7 +31,15 @@ $OC_Version = array(12, 0, 0, 12);
 // The human readable string
 $OC_VersionString = '12.0 alpha';
 
-$OC_VersionCanBeUpgradedFrom = array(11);
+$OC_VersionCanBeUpgradedFrom = [
+	'nextcloud' => [
+		'11.0' => true,
+		'12.0' => true,
+	],
+	'owncloud' => [
+		'10.0' => true,
+	],
+];
 
 // default Nextcloud channel
 $OC_Channel = 'git';