diff --git a/enterprise/frontend/src/embedding-sdk/config.ts b/enterprise/frontend/src/embedding-sdk/config.ts
index f044d9038996c97a75ae321da60683696c1a5f76..fadb7ae907ea2caed0be24daa594671762cf39c7 100644
--- a/enterprise/frontend/src/embedding-sdk/config.ts
+++ b/enterprise/frontend/src/embedding-sdk/config.ts
@@ -4,5 +4,5 @@ export const EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID = "metabase-sdk-portal-root";
 export const EMBEDDING_SDK_FULL_PAGE_PORTAL_ROOT_ELEMENT_ID =
   "metabase-sdk-full-page-portal-root";
 
-export const getEmbeddingSdkVersion = () =>
-  process.env.EMBEDDING_SDK_VERSION ?? "unknown";
+export const getEmbeddingSdkVersion = (): string | "unknown" =>
+  (process.env.EMBEDDING_SDK_VERSION as string) ?? "unknown";
diff --git a/enterprise/frontend/src/embedding-sdk/lib/log-utils.ts b/enterprise/frontend/src/embedding-sdk/lib/log-utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d9b2f5e745c0fe1478eeae06df60ca3624fa58b5
--- /dev/null
+++ b/enterprise/frontend/src/embedding-sdk/lib/log-utils.ts
@@ -0,0 +1,20 @@
+// Note: this functions need to return an array of two elements, when styling
+// console.logs, the style needs to passed as second argument
+// To use them, do `console.log(...bigWarningHeader("message"), "rest of the message")`
+
+// Note 2: why do we even need those? Because at the moment the SDK may log a
+// lot of exceptions, we need to make actionable messages stand out
+
+export const bigWarningHeader = (message: string) => {
+  return [
+    `%c${message}\n`,
+    "color: #FCF0A6; font-size: 16px; font-weight: bold;",
+  ];
+};
+
+export const bigErrorHeader = (message: string) => {
+  return [
+    `%c${message}\n`,
+    "color: #FF2222; font-size: 16px; font-weight: bold;",
+  ];
+};
diff --git a/enterprise/frontend/src/embedding-sdk/lib/version-utils.ts b/enterprise/frontend/src/embedding-sdk/lib/version-utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1322144671e8a80989f8cdf925b2799e3bc20b92
--- /dev/null
+++ b/enterprise/frontend/src/embedding-sdk/lib/version-utils.ts
@@ -0,0 +1,13 @@
+import { versionToNumericComponents } from "metabase/lib/utils";
+
+export const isSdkVersionCompatibleWithMetabaseVersion = ({
+  mbVersion,
+  sdkVersion,
+}: {
+  mbVersion: string;
+  sdkVersion: string;
+}) => {
+  const mbVersionComponents = versionToNumericComponents(mbVersion);
+  const sdkVersionComponents = versionToNumericComponents(sdkVersion);
+  return mbVersionComponents?.[1] === sdkVersionComponents?.[1];
+};
diff --git a/enterprise/frontend/src/embedding-sdk/lib/version-utils.unit.spec.ts b/enterprise/frontend/src/embedding-sdk/lib/version-utils.unit.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8c6214e1ac56af8d554271296329b30708c4e18a
--- /dev/null
+++ b/enterprise/frontend/src/embedding-sdk/lib/version-utils.unit.spec.ts
@@ -0,0 +1,92 @@
+import { isSdkVersionCompatibleWithMetabaseVersion } from "./version-utils";
+
+const expectCompatibility = ({
+  mbVersion,
+  sdkVersion,
+  expected,
+}: {
+  mbVersion: string;
+  sdkVersion: string;
+  expected: boolean;
+}) => {
+  it(`expect sdk version ${sdkVersion} and mb version ${mbVersion} to be ${expected ? "compatible" : "incompatible"}`, () => {
+    expect(
+      isSdkVersionCompatibleWithMetabaseVersion({
+        mbVersion,
+        sdkVersion,
+      }),
+    ).toBe(expected);
+  });
+};
+
+describe('sdk version utils, naming used: "{0,1}.{major}.{minor}"', () => {
+  describe('should return true only if the "major" version is the same', () => {
+    expectCompatibility({
+      mbVersion: "v0.52.10",
+      sdkVersion: "0.52.10",
+      expected: true,
+    });
+    expectCompatibility({
+      mbVersion: "v1.50.10",
+      sdkVersion: "0.51.10",
+      expected: false,
+    });
+    expectCompatibility({
+      mbVersion: "v1.50.10",
+      sdkVersion: "0.53.10",
+      expected: false,
+    });
+  });
+
+  describe('should ignore "minors"', () => {
+    expectCompatibility({
+      mbVersion: "v1.50.10",
+      sdkVersion: "0.50.11",
+      expected: true,
+    });
+
+    expectCompatibility({
+      mbVersion: "v1.50.10",
+      sdkVersion: "0.50.9",
+      expected: true,
+    });
+  });
+
+  describe("sdk version 0.xx.yy should be compatible both with MB 0.xx.yy (OSS) and 1.xx.yy (EE)", () => {
+    expectCompatibility({
+      mbVersion: "v0.52.10",
+      sdkVersion: "0.52.10",
+      expected: true,
+    });
+
+    expectCompatibility({
+      mbVersion: "v1.52.10",
+      sdkVersion: "0.52.10",
+      expected: true,
+    });
+  });
+
+  describe("should ignore build tags like snapshot, alpha, beta, rc", () => {
+    for (const tag of ["snapshot", "alpha", "beta", "rc", "X-NOT-EXISTING"]) {
+      expectCompatibility({
+        mbVersion: `v0.52.10-${tag}`,
+        sdkVersion: "0.52.10",
+        expected: true,
+      });
+    }
+  });
+
+  describe("should handle versions of the sdk wrapped in double quotes (metabase#50014)", () => {
+    expectCompatibility({
+      mbVersion: "v1.55.0",
+      sdkVersion: '"0.55.0"',
+      expected: true,
+    });
+
+    expectCompatibility({
+      mbVersion: "v1.55.0",
+      sdkVersion: '"0.54.0"',
+      expected: false,
+    });
+  });
+});
diff --git a/enterprise/frontend/src/embedding-sdk/store/auth.ts b/enterprise/frontend/src/embedding-sdk/store/auth.ts
index 100d9ac5dc5f314f278804a28300a4e163f3f4a3..d0cd2c8b5fed62d93fc4587319fccf2643afd63b 100644
--- a/enterprise/frontend/src/embedding-sdk/store/auth.ts
+++ b/enterprise/frontend/src/embedding-sdk/store/auth.ts
@@ -3,7 +3,10 @@ import type {
   FetchRequestTokenFn,
   SDKConfig,
 } from "embedding-sdk";
+import { getEmbeddingSdkVersion } from "embedding-sdk/config";
 import { getIsLocalhost } from "embedding-sdk/lib/is-localhost";
+import { bigErrorHeader, bigWarningHeader } from "embedding-sdk/lib/log-utils";
+import { isSdkVersionCompatibleWithMetabaseVersion } from "embedding-sdk/lib/version-utils";
 import type { SdkStoreState } from "embedding-sdk/store/types";
 import api from "metabase/lib/api";
 import { createAsyncThunk } from "metabase/lib/redux";
@@ -43,6 +46,25 @@ export const initAuth = createAsyncThunk(
       dispatch(refreshSiteSettings({})),
     ]);
 
+    const mbVersion = siteSettings.payload?.version?.tag;
+    const sdkVersion = getEmbeddingSdkVersion();
+
+    if (mbVersion && sdkVersion !== "unknown") {
+      if (
+        !isSdkVersionCompatibleWithMetabaseVersion({
+          mbVersion,
+          sdkVersion,
+        })
+      ) {
+        console.warn(
+          ...bigWarningHeader("Detected SDK compatibility issue"),
+          `SDK version ${sdkVersion} is not compatible with MB version ${mbVersion}, this might cause issues.`,
+          // eslint-disable-next-line no-unconditional-metabase-links-render -- console log in case of issues
+          "Learn more at https://www.metabase.com/docs/latest/embedding/sdk/version",
+        );
+      }
+    }
+
     if (!user.payload) {
       // The refresh user thunk just returns null if it fails to fetch the user, it doesn't throw
       const error = new Error(
@@ -113,11 +135,7 @@ export const refreshTokenAsync = createAsyncThunk(
 
       // The host app may have a lot of logs (and the sdk logs a lot too), so we
       // make a big red error message to make it visible as this is 90% a blocking error
-      console.error(
-        "%cFailed to get auth session\n",
-        "color: #FF2222; font-size: 16px; font-weight: bold;",
-        exception,
-      );
+      console.error(...bigErrorHeader("Failed to get auth session"), exception);
 
       throw exception;
     }
diff --git a/enterprise/frontend/src/embedding-sdk/test/sdk-compatibility-warning.unit.spec.tsx b/enterprise/frontend/src/embedding-sdk/test/sdk-compatibility-warning.unit.spec.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..679e9aa6d2a2a6f68e700441a0b272b442b31f36
--- /dev/null
+++ b/enterprise/frontend/src/embedding-sdk/test/sdk-compatibility-warning.unit.spec.tsx
@@ -0,0 +1,116 @@
+import { render } from "@testing-library/react";
+import fetchMock from "fetch-mock";
+
+import {
+  setupCurrentUserEndpoint,
+  setupPropertiesEndpoints,
+} from "__support__/server-mocks";
+import { waitForLoaderToBeRemoved } from "__support__/ui";
+import {
+  MetabaseProvider,
+  defineEmbeddingSdkConfig,
+} from "embedding-sdk/components/public";
+import {
+  createMockSettings,
+  createMockTokenFeatures,
+  createMockUser,
+  createMockVersion,
+} from "metabase-types/api/mocks";
+
+import { getEmbeddingSdkVersion } from "../config";
+
+// TODO: extract this common setup to a shared util
+const METABASE_INSTANCE_URL = "path:";
+const AUTH_PROVIDER_URL = "http://auth-provider/metabase-sso";
+
+const defaultAuthUriConfig = defineEmbeddingSdkConfig({
+  metabaseInstanceUrl: METABASE_INSTANCE_URL,
+  authProviderUri: AUTH_PROVIDER_URL,
+  fetchRequestToken: _ =>
+    Promise.resolve({
+      id: "123",
+      exp: Number.MAX_SAFE_INTEGER,
+    }),
+});
+
+jest.mock("../config", () => ({
+  getEmbeddingSdkVersion: jest.fn(),
+}));
+
+const setup = async ({
+  sdkVersion,
+  mbVersion,
+}: {
+  sdkVersion: string;
+  mbVersion: string;
+}) => {
+  (getEmbeddingSdkVersion as jest.Mock).mockReturnValue(sdkVersion);
+  setupPropertiesEndpoints(
+    createMockSettings({
+      "token-features": createMockTokenFeatures({
+        embedding_sdk: true,
+      }),
+      version: createMockVersion({ tag: mbVersion }),
+    }),
+  );
+  setupCurrentUserEndpoint(createMockUser({ id: 1 }));
+
+  render(
+    <MetabaseProvider config={defaultAuthUriConfig}>
+      <div>Hello</div>
+    </MetabaseProvider>,
+  );
+  await waitForLoaderToBeRemoved();
+};
+
+let consoleWarnSpy: jest.SpyInstance;
+
+const getWarnMessages = (): string[] =>
+  consoleWarnSpy.mock.calls.map(callArguments => callArguments.join(" "));
+
+describe("SDK auth errors", () => {
+  beforeEach(() => {
+    fetchMock.reset();
+
+    consoleWarnSpy = jest.spyOn(console, "warn").mockImplementation(() => {});
+    (getEmbeddingSdkVersion as jest.Mock).mockClear();
+  });
+
+  afterEach(() => {
+    jest.resetAllMocks();
+  });
+
+  describe("SDK version compatibility", () => {
+    it("should show a message when the SDK version is not compatible with the Metabase version", async () => {
+      await setup({ sdkVersion: "0.52.10", mbVersion: "v1.55.0" });
+
+      expect(
+        getWarnMessages().filter(message =>
+          message.includes(
+            "SDK version 0.52.10 is not compatible with MB version v1.55.0, this might cause issues.",
+          ),
+        ),
+      ).toHaveLength(1);
+    });
+
+    it("should not show a warning when the SDK version is compatible with the Metabase version", async () => {
+      await setup({ sdkVersion: "0.55.10", mbVersion: "v1.55.1" });
+
+      expect(
+        getWarnMessages().filter(message =>
+          message.includes("is not compatible"),
+        ),
+      ).toHaveLength(0);
+    });
+
+    it("should not show the warning when the sdk version is unknown", async () => {
+      await setup({ sdkVersion: "unknown", mbVersion: "v1.55.1" });
+
+      expect(
+        getWarnMessages().filter(message =>
+          message.includes("is not compatible"),
+        ),
+      ).toHaveLength(0);
+    });
+  });
+});