diff --git a/lib/shared/version-utils.js b/lib/shared/version-utils.js
--- a/lib/shared/version-utils.js
+++ b/lib/shared/version-utils.js
@@ -1,6 +1,10 @@
 // @flow
 
-import { type PlatformDetails, isWebPlatform } from '../types/device-types.js';
+import {
+  type PlatformDetails,
+  isWebPlatform,
+  isDesktopPlatform,
+} from '../types/device-types.js';
 
 /**
  * A code version used for features that are waiting to be released
@@ -16,20 +20,33 @@
 
 function hasMinCodeVersion(
   platformDetails: ?PlatformDetails,
-  minCodeVersion: Partial<{ +native: number, +web: number }>,
+  minCodeVersion: Partial<{
+    +native: number,
+    +web: number,
+    +majorDesktop: number,
+  }>,
 ): boolean {
   if (!platformDetails) {
     return true;
   }
-  const { codeVersion } = platformDetails;
+
+  const { codeVersion, majorDesktopVersion } = platformDetails;
   const minVersion = isWebPlatform(platformDetails.platform)
     ? minCodeVersion.web
     : minCodeVersion.native;
 
-  if (!minVersion) {
-    return true;
+  const minMajorDesktopVersion = isDesktopPlatform(platformDetails.platform)
+    ? minCodeVersion.majorDesktop
+    : undefined;
+
+  if (minVersion && (!codeVersion || codeVersion < minVersion)) {
+    return false;
   }
-  if (!codeVersion || codeVersion < minVersion) {
+
+  if (
+    minMajorDesktopVersion &&
+    (!majorDesktopVersion || majorDesktopVersion < minMajorDesktopVersion)
+  ) {
     return false;
   }
 
@@ -58,9 +75,14 @@
   return true;
 }
 
+function extractMajorDesktopVersion(desktopVersion: string): number {
+  return desktopVersion.split('.').map(Number)[0];
+}
+
 export {
   FUTURE_CODE_VERSION,
   NEXT_CODE_VERSION,
   hasMinCodeVersion,
   hasMinStateVersion,
+  extractMajorDesktopVersion,
 };
diff --git a/lib/types/device-types.js b/lib/types/device-types.js
--- a/lib/types/device-types.js
+++ b/lib/types/device-types.js
@@ -25,8 +25,12 @@
   return deviceType;
 }
 
+export function isDesktopPlatform(platform: ?string): boolean {
+  return platform === 'macos' || platform === 'windows';
+}
+
 export function isWebPlatform(platform: ?string): boolean {
-  return platform === 'web' || platform === 'windows' || platform === 'macos';
+  return platform === 'web' || isDesktopPlatform(platform);
 }
 
 export type DeviceTokenUpdateRequest = {
@@ -39,6 +43,7 @@
   +platform: Platform,
   +codeVersion?: ?number,
   +stateVersion?: ?number,
+  +majorDesktopVersion?: number,
 };
 
 export type LastCommunicatedPlatformDetails = {
diff --git a/lib/utils/validation-utils.js b/lib/utils/validation-utils.js
--- a/lib/utils/validation-utils.js
+++ b/lib/utils/validation-utils.js
@@ -70,6 +70,7 @@
   platform: tPlatform,
   codeVersion: t.maybe(t.Number),
   stateVersion: t.maybe(t.Number),
+  majorDesktopVersion: t.maybe(t.Number),
 });
 const tPassword: TRefinement<string> = t.refinement(
   t.String,
diff --git a/web/app.react.js b/web/app.react.js
--- a/web/app.react.js
+++ b/web/app.react.js
@@ -25,6 +25,7 @@
   combineLoadingStatuses,
 } from 'lib/selectors/loading-selectors.js';
 import { isLoggedIn } from 'lib/selectors/user-selectors.js';
+import { extractMajorDesktopVersion } from 'lib/shared/version-utils.js';
 import { TunnelbrokerProvider } from 'lib/tunnelbroker/tunnelbroker-context.js';
 import type { LoadingStatus } from 'lib/types/loading-types.js';
 import type { Dispatch } from 'lib/types/redux-types.js';
@@ -82,6 +83,9 @@
 import '@fortawesome/fontawesome-svg-core/styles.css';
 
 faConfig.autoAddCss = false;
+const desktopDetails = electron?.version
+  ? { majorDesktopVersion: extractMajorDesktopVersion(electron?.version) }
+  : null;
 
 registerConfig({
   // We can't securely cache credentials on web, so we have no way to recover
@@ -94,6 +98,7 @@
     platform: electron?.platform ?? 'web',
     codeVersion: 45,
     stateVersion: persistConfig.version,
+    ...desktopDetails,
   },
 });