diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8a9378fa4..53788537f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -42,6 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - The `sha256()` function no longer throws on statically known strings of any length: PR [#907](https://github.com/tact-lang/tact/pull/907)
 - TypeScript wrappers generation for messages with single quote: PR [#1106](https://github.com/tact-lang/tact/pull/1106)
 - `foreach` loops now properly handle `as coins` map value serialization type: PR [#1186](https://github.com/tact-lang/tact/pull/1186)
+- The typechecker now rejects integer map key types with variable width (`coins`, `varint16`, `varint32`, `varuint16`, `varuint32`): PR [#1276](https://github.com/tact-lang/tact/pull/1276)
 
 ### Docs
 
diff --git a/src/abi/map.ts b/src/abi/map.ts
index 2c0332b1f..d2c52c783 100644
--- a/src/abi/map.ts
+++ b/src/abi/map.ts
@@ -74,21 +74,27 @@ function checkValueType(
 }
 
 function resolveMapKeyBits(
-    self: { key: string; keyAs: string | null },
-    ref: SrcInfo,
+    type: { key: string; keyAs: string | null },
+    loc: SrcInfo,
 ): { bits: number; kind: string } {
-    if (self.key === "Int") {
-        if (self.keyAs?.startsWith("int")) {
-            return { bits: parseInt(self.keyAs.slice(3), 10), kind: "int" };
+    if (type.key === "Int") {
+        if (type.keyAs === null) {
+            return { bits: 257, kind: "int" }; // Default for "Int" keys
+        }
+        if (type.keyAs.startsWith("int")) {
+            return { bits: parseInt(type.keyAs.slice(3), 10), kind: "int" };
         }
-        if (self.keyAs?.startsWith("uint")) {
-            return { bits: parseInt(self.keyAs.slice(4), 10), kind: "uint" };
+        if (type.keyAs.startsWith("uint")) {
+            return { bits: parseInt(type.keyAs.slice(4), 10), kind: "uint" };
         }
-        return { bits: 257, kind: "int" }; // Default for "Int" keys
-    } else if (self.key === "Address") {
+        throwCompilationError(
+            `Unsupported integer map key type storage annotation: ${type.keyAs}`,
+            loc,
+        );
+    } else if (type.key === "Address") {
         return { bits: 267, kind: "slice" };
     }
-    throwCompilationError(`Unsupported key type: ${self.key}`, ref);
+    throwCompilationError(`Unsupported key type: ${type.key}`, loc);
 }
 
 function handleStructOrOtherValue(
diff --git a/src/types/__snapshots__/resolveDescriptors.spec.ts.snap b/src/types/__snapshots__/resolveDescriptors.spec.ts.snap
index 1b1cd6331..976d617ec 100644
--- a/src/types/__snapshots__/resolveDescriptors.spec.ts.snap
+++ b/src/types/__snapshots__/resolveDescriptors.spec.ts.snap
@@ -672,6 +672,56 @@ Line 6, col 29:
 "
 `;
 
+exports[`resolveDescriptors should fail descriptors for wf-type-contract-incorrect-map-key-annotation-coins 1`] = `
+"<unknown>:6:19: "coins" is invalid as-annotation for map key type "Int"
+Line 6, col 19:
+  5 | contract Test {
+> 6 |     m: map<Int as coins, Address> = emptyMap();
+                        ^~~~~
+  7 | }
+"
+`;
+
+exports[`resolveDescriptors should fail descriptors for wf-type-contract-incorrect-map-key-annotation-varint16 1`] = `
+"<unknown>:6:19: "varint16" is invalid as-annotation for map key type "Int"
+Line 6, col 19:
+  5 | contract Test {
+> 6 |     m: map<Int as varint16, Address> = emptyMap();
+                        ^~~~~~~~
+  7 | }
+"
+`;
+
+exports[`resolveDescriptors should fail descriptors for wf-type-contract-incorrect-map-key-annotation-varint32 1`] = `
+"<unknown>:6:19: "varint32" is invalid as-annotation for map key type "Int"
+Line 6, col 19:
+  5 | contract Test {
+> 6 |     m: map<Int as varint32, Address> = emptyMap();
+                        ^~~~~~~~
+  7 | }
+"
+`;
+
+exports[`resolveDescriptors should fail descriptors for wf-type-contract-incorrect-map-key-annotation-varuint16 1`] = `
+"<unknown>:6:19: "varuint16" is invalid as-annotation for map key type "Int"
+Line 6, col 19:
+  5 | contract Test {
+> 6 |     m: map<Int as varuint16, Address> = emptyMap();
+                        ^~~~~~~~~
+  7 | }
+"
+`;
+
+exports[`resolveDescriptors should fail descriptors for wf-type-contract-incorrect-map-key-annotation-varuint32 1`] = `
+"<unknown>:6:19: "varuint32" is invalid as-annotation for map key type "Int"
+Line 6, col 19:
+  5 | contract Test {
+> 6 |     m: map<Int as varuint32, Address> = emptyMap();
+                        ^~~~~~~~~
+  7 | }
+"
+`;
+
 exports[`resolveDescriptors should fail descriptors for wf-type-fun-param 1`] = `
 "<unknown>:4:16: Invalid map type. Check https://docs.tact-lang.org/book/maps#allowed-types
 Line 4, col 16:
diff --git a/src/types/resolveABITypeRef.ts b/src/types/resolveABITypeRef.ts
index b343e421f..b2cf8e731 100644
--- a/src/types/resolveABITypeRef.ts
+++ b/src/types/resolveABITypeRef.ts
@@ -29,15 +29,17 @@ type FormatDef = Record<
 >;
 
 const uintOptions: FormatDef = Object.fromEntries(
-    [...Array(257).keys()]
-        .slice(1)
-        .map((key) => [`uint${key}`, { type: "uint", format: key }]),
+    [...Array(256).keys()].map((key) => [
+        `uint${key + 1}`,
+        { type: "uint", format: key + 1 },
+    ]),
 );
 
 const intOptions: FormatDef = Object.fromEntries(
-    [...Array(257).keys()]
-        .slice(1)
-        .map((key) => [`int${key}`, { type: "int", format: key }]),
+    [...Array(256).keys()].map((key) => [
+        `int${key + 1}`,
+        { type: "int", format: key + 1 },
+    ]),
 );
 
 const intFormats: FormatDef = {
@@ -51,7 +53,14 @@ const intFormats: FormatDef = {
     varuint32: { type: "uint", format: "varuint32" },
 };
 
-export const intMapFormats: FormatDef = { ...intFormats };
+// only fixed-width integer map keys are supported
+export const intMapKeyFormats: FormatDef = {
+    ...uintOptions,
+    ...intOptions,
+    int257: { type: "int", format: 257 },
+};
+
+export const intMapValFormats: FormatDef = { ...intFormats };
 
 const cellFormats: FormatDef = {
     remaining: { type: "cell", format: "remainder" },
@@ -259,8 +268,9 @@ export function resolveABIType(src: AstFieldDecl): ABITypeRef {
         if (isInt(src.type.keyType)) {
             key = "int";
             if (src.type.keyStorageType) {
-                const format = intMapFormats[idText(src.type.keyStorageType)];
-                if (!format || format.format === "coins") {
+                const format =
+                    intMapKeyFormats[idText(src.type.keyStorageType)];
+                if (!format) {
                     throwCompilationError(
                         `Unsupported format ${idTextErr(src.type.keyStorageType)} for map key`,
                         src.loc,
@@ -288,7 +298,8 @@ export function resolveABIType(src: AstFieldDecl): ABITypeRef {
         if (isInt(src.type.valueType)) {
             value = "int";
             if (src.type.valueStorageType) {
-                const format = intMapFormats[idText(src.type.valueStorageType)];
+                const format =
+                    intMapValFormats[idText(src.type.valueStorageType)];
                 if (!format) {
                     throwCompilationError(
                         `Unsupported format ${idText(src.type.valueStorageType)} for map value`,
@@ -424,8 +435,8 @@ export function createABITypeRefFromTypeRef(
         if (src.key === "Int") {
             key = "int";
             if (src.keyAs) {
-                const format = intMapFormats[src.keyAs];
-                if (!format || src.keyAs === "coins") {
+                const format = intMapKeyFormats[src.keyAs];
+                if (!format) {
                     throwCompilationError(
                         `Unsupported format ${src.keyAs} for map key`,
                         loc,
@@ -450,7 +461,7 @@ export function createABITypeRefFromTypeRef(
         if (src.value === "Int") {
             value = "int";
             if (src.valueAs) {
-                const format = intMapFormats[src.valueAs];
+                const format = intMapValFormats[src.valueAs];
                 if (!format) {
                     throwCompilationError(
                         `Unsupported format ${src.valueAs} for map value`,
diff --git a/src/types/resolveDescriptors.ts b/src/types/resolveDescriptors.ts
index bd5976596..2f01f4c9e 100644
--- a/src/types/resolveDescriptors.ts
+++ b/src/types/resolveDescriptors.ts
@@ -45,7 +45,11 @@ import { cloneNode } from "../grammar/clone";
 import { crc16 } from "../utils/crc16";
 import { isSubsetOf } from "../utils/isSubsetOf";
 import { evalConstantExpression } from "../constEval";
-import { resolveABIType, intMapFormats } from "./resolveABITypeRef";
+import {
+    resolveABIType,
+    intMapKeyFormats,
+    intMapValFormats,
+} from "./resolveABITypeRef";
 import { enabledExternals } from "../config/features";
 import { isRuntimeType } from "./isRuntimeType";
 import { GlobalFunctions } from "../abi/global";
@@ -62,17 +66,28 @@ const staticConstantsStore = createContextStore<ConstantDescription>();
 function verifyMapAsAnnotationsForPrimitiveTypes(
     type: AstTypeId,
     asAnnotation: AstId | null,
+    kind: "keyType" | "valType",
 ): void {
     switch (idText(type)) {
         case "Int": {
-            if (
-                asAnnotation !== null &&
-                !Object.keys(intMapFormats).includes(idText(asAnnotation))
-            ) {
-                throwCompilationError(
-                    'Invalid `as`-annotation for type "Int" type',
-                    asAnnotation.loc,
-                );
+            if (asAnnotation === null) return;
+            const ann = idText(asAnnotation);
+            switch (kind) {
+                case "keyType":
+                    if (!Object.keys(intMapKeyFormats).includes(ann)) {
+                        throwCompilationError(
+                            `"${ann}" is invalid as-annotation for map key type "Int"`,
+                            asAnnotation.loc,
+                        );
+                    }
+                    return;
+                case "valType":
+                    if (!Object.keys(intMapValFormats).includes(ann)) {
+                        throwCompilationError(
+                            `"${ann}" is invalid as-annotation for map value type "Int"`,
+                            asAnnotation.loc,
+                        );
+                    }
             }
             return;
         }
@@ -97,6 +112,7 @@ function verifyMapTypes(
     typeId: AstTypeId,
     asAnnotation: AstId | null,
     allowedTypeNames: string[],
+    kind: "keyType" | "valType",
 ): void {
     if (!allowedTypeNames.includes(idText(typeId))) {
         throwCompilationError(
@@ -104,26 +120,31 @@ function verifyMapTypes(
             typeId.loc,
         );
     }
-    verifyMapAsAnnotationsForPrimitiveTypes(typeId, asAnnotation);
+    verifyMapAsAnnotationsForPrimitiveTypes(typeId, asAnnotation, kind);
 }
 
 function verifyMapType(mapTy: AstMapType, isValTypeStruct: boolean) {
     // optional and other compound key and value types are disallowed at the level of grammar
 
     // check allowed key types
-    verifyMapTypes(mapTy.keyType, mapTy.keyStorageType, ["Int", "Address"]);
+    verifyMapTypes(
+        mapTy.keyType,
+        mapTy.keyStorageType,
+        ["Int", "Address"],
+        "keyType",
+    );
 
     // check allowed value types
     if (isValTypeStruct && mapTy.valueStorageType === null) {
         return;
     }
     // the case for struct/message is already checked
-    verifyMapTypes(mapTy.valueType, mapTy.valueStorageType, [
-        "Int",
-        "Address",
-        "Bool",
-        "Cell",
-    ]);
+    verifyMapTypes(
+        mapTy.valueType,
+        mapTy.valueStorageType,
+        ["Int", "Address", "Bool", "Cell"],
+        "valType",
+    );
 }
 
 export const toBounced = (type: string) => `${type}%%BOUNCED%%`;
diff --git a/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-coins.tact b/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-coins.tact
new file mode 100644
index 000000000..e309de586
--- /dev/null
+++ b/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-coins.tact
@@ -0,0 +1,8 @@
+primitive Int;
+primitive Address;
+trait BaseTrait {}
+
+contract Test {
+    m: map<Int as coins, Address> = emptyMap();
+}
+
diff --git a/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-varint16.tact b/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-varint16.tact
new file mode 100644
index 000000000..80f11f809
--- /dev/null
+++ b/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-varint16.tact
@@ -0,0 +1,8 @@
+primitive Int;
+primitive Address;
+trait BaseTrait {}
+
+contract Test {
+    m: map<Int as varint16, Address> = emptyMap();
+}
+
diff --git a/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-varint32.tact b/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-varint32.tact
new file mode 100644
index 000000000..d5ea502d0
--- /dev/null
+++ b/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-varint32.tact
@@ -0,0 +1,8 @@
+primitive Int;
+primitive Address;
+trait BaseTrait {}
+
+contract Test {
+    m: map<Int as varint32, Address> = emptyMap();
+}
+
diff --git a/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-varuint16.tact b/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-varuint16.tact
new file mode 100644
index 000000000..56830db68
--- /dev/null
+++ b/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-varuint16.tact
@@ -0,0 +1,8 @@
+primitive Int;
+primitive Address;
+trait BaseTrait {}
+
+contract Test {
+    m: map<Int as varuint16, Address> = emptyMap();
+}
+
diff --git a/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-varuint32.tact b/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-varuint32.tact
new file mode 100644
index 000000000..ead6afbb7
--- /dev/null
+++ b/src/types/test-failed/wf-type-contract-incorrect-map-key-annotation-varuint32.tact
@@ -0,0 +1,8 @@
+primitive Int;
+primitive Address;
+trait BaseTrait {}
+
+contract Test {
+    m: map<Int as varuint32, Address> = emptyMap();
+}
+