diff --git a/mirai-core-api/src/commonMain/kotlin/utils/DeviceInfo.kt b/mirai-core-api/src/commonMain/kotlin/utils/DeviceInfo.kt
index 18eab00b0..6f8a4e0aa 100644
--- a/mirai-core-api/src/commonMain/kotlin/utils/DeviceInfo.kt
+++ b/mirai-core-api/src/commonMain/kotlin/utils/DeviceInfo.kt
@@ -12,7 +12,6 @@ package net.mamoe.mirai.utils
 import io.ktor.utils.io.core.*
 import kotlinx.serialization.KSerializer
 import kotlinx.serialization.Serializable
-import kotlinx.serialization.Serializer
 import kotlinx.serialization.Transient
 import kotlinx.serialization.builtins.serializer
 import kotlinx.serialization.json.Json
@@ -77,6 +76,8 @@ public expect class DeviceInfo(
     @MiraiInternalApi
     public val guid: ByteArray
 
+
+    // @Serializable: use DeviceInfoVersionSerializer in commonMain.
     public class Version(
         incremental: ByteArray = "5891938".toByteArray(),
         release: ByteArray = "10".toByteArray(),
@@ -288,8 +289,23 @@ internal object DeviceInfoManager {
         val data: T
     )
 
-    @Serializer(forClass = DeviceInfo.Version::class)
-    private object DeviceInfoVersionSerializer
+    private object DeviceInfoVersionSerializer : KSerializer<DeviceInfo.Version> by SerialData.serializer().map(
+        resultantDescriptor = SerialData.serializer().descriptor.copy("Version"),
+        deserialize = {
+            DeviceInfo.Version(incremental, release, codename, sdk)
+        },
+        serialize = {
+            SerialData(incremental, release, codename, sdk)
+        }
+    ) {
+        @Serializable
+        private class SerialData(
+            val incremental: ByteArray = "5891938".toByteArray(),
+            val release: ByteArray = "10".toByteArray(),
+            val codename: ByteArray = "REL".toByteArray(),
+            val sdk: Int = 29
+        )
+    }
 
     @Serializable
     class V1(
diff --git a/mirai-core-api/src/commonTest/resources/device/legacy-device-info-1.json b/mirai-core-api/src/commonTest/resources/device/legacy-device-info-1.json
new file mode 100644
index 000000000..22a0ed933
--- /dev/null
+++ b/mirai-core-api/src/commonTest/resources/device/legacy-device-info-1.json
@@ -0,0 +1,354 @@
+{
+  "display" : [
+    77,
+    73,
+    82,
+    65,
+    73,
+    46,
+    55,
+    56,
+    49,
+    56,
+    55,
+    57,
+    46,
+    48,
+    48,
+    49
+  ],
+  "product" : [
+    109,
+    105,
+    114,
+    97,
+    105
+  ],
+  "device" : [
+    109,
+    105,
+    114,
+    97,
+    105
+  ],
+  "board" : [
+    109,
+    105,
+    114,
+    97,
+    105
+  ],
+  "brand" : [
+    109,
+    97,
+    109,
+    111,
+    101
+  ],
+  "model" : [
+    109,
+    105,
+    114,
+    97,
+    105
+  ],
+  "bootloader" : [
+    117,
+    110,
+    107,
+    110,
+    111,
+    119,
+    110
+  ],
+  "fingerprint" : [
+    109,
+    97,
+    109,
+    111,
+    101,
+    47,
+    109,
+    105,
+    114,
+    97,
+    105,
+    47,
+    109,
+    105,
+    114,
+    97,
+    105,
+    58,
+    49,
+    48,
+    47,
+    77,
+    73,
+    82,
+    65,
+    73,
+    46,
+    50,
+    48,
+    48,
+    49,
+    50,
+    50,
+    46,
+    48,
+    48,
+    49,
+    47,
+    53,
+    56,
+    52,
+    54,
+    51,
+    56,
+    49,
+    58,
+    117,
+    115,
+    101,
+    114,
+    47,
+    114,
+    101,
+    108,
+    101,
+    97,
+    115,
+    101,
+    45,
+    107,
+    101,
+    121,
+    115
+  ],
+  "bootId" : [
+    56,
+    53,
+    57,
+    67,
+    67,
+    54,
+    52,
+    65,
+    45,
+    57,
+    65,
+    69,
+    57,
+    45,
+    56,
+    48,
+    67,
+    51,
+    45,
+    66,
+    51,
+    68,
+    52,
+    45,
+    51,
+    49,
+    70,
+    49,
+    49,
+    67,
+    56,
+    67,
+    54,
+    66,
+    56,
+    52
+  ],
+  "procVersion" : [
+    76,
+    105,
+    110,
+    117,
+    120,
+    32,
+    118,
+    101,
+    114,
+    115,
+    105,
+    111,
+    110,
+    32,
+    51,
+    46,
+    48,
+    46,
+    51,
+    49,
+    45,
+    48,
+    84,
+    102,
+    51,
+    68,
+    50,
+    53,
+    67,
+    32,
+    40,
+    97,
+    110,
+    100,
+    114,
+    111,
+    105,
+    100,
+    45,
+    98,
+    117,
+    105,
+    108,
+    100,
+    64,
+    120,
+    120,
+    120,
+    46,
+    120,
+    120,
+    120,
+    46,
+    120,
+    120,
+    120,
+    46,
+    120,
+    120,
+    120,
+    46,
+    99,
+    111,
+    109,
+    41
+  ],
+  "baseBand" : [
+  ],
+  "version" : {
+    "incremental" : [
+      53,
+      56,
+      57,
+      49,
+      57,
+      51,
+      56
+    ],
+    "release" : [
+      49,
+      48
+    ],
+    "codename" : [
+      82,
+      69,
+      76
+    ]
+  },
+  "simInfo" : [
+    84,
+    45,
+    77,
+    111,
+    98,
+    105,
+    108,
+    101
+  ],
+  "osType" : [
+    97,
+    110,
+    100,
+    114,
+    111,
+    105,
+    100
+  ],
+  "macAddress" : [
+    48,
+    50,
+    58,
+    48,
+    48,
+    58,
+    48,
+    48,
+    58,
+    48,
+    48,
+    58,
+    48,
+    48,
+    58,
+    48,
+    48
+  ],
+  "wifiBSSID" : [
+    48,
+    50,
+    58,
+    48,
+    48,
+    58,
+    48,
+    48,
+    58,
+    48,
+    48,
+    58,
+    48,
+    48,
+    58,
+    48,
+    48
+  ],
+  "wifiSSID" : [
+    60,
+    117,
+    110,
+    107,
+    110,
+    111,
+    119,
+    110,
+    32,
+    115,
+    115,
+    105,
+    100,
+    62
+  ],
+  "imsiMd5" : [
+    69,
+    45,
+    31,
+    44,
+    85,
+    103,
+    -19,
+    88,
+    21,
+    -47,
+    94,
+    -128,
+    38,
+    -45,
+    9,
+    50
+  ],
+  "imei" : "101633900250935",
+  "apn" : [
+    119,
+    105,
+    102,
+    105
+  ]
+}
\ No newline at end of file
diff --git a/mirai-core-api/src/jvmBaseTest/kotlin/utils/JvmDeviceInfoTest.kt b/mirai-core-api/src/jvmBaseTest/kotlin/utils/JvmDeviceInfoTest.kt
index 0272b6d58..7a5099516 100644
--- a/mirai-core-api/src/jvmBaseTest/kotlin/utils/JvmDeviceInfoTest.kt
+++ b/mirai-core-api/src/jvmBaseTest/kotlin/utils/JvmDeviceInfoTest.kt
@@ -11,9 +11,9 @@ package net.mamoe.mirai.utils
 
 import kotlinx.serialization.json.Json
 import net.mamoe.mirai.utils.DeviceInfo.Companion.loadAsDeviceInfo
-import kotlin.test.Test
 import org.junit.jupiter.api.io.TempDir
 import java.io.File
+import kotlin.test.Test
 import kotlin.test.assertEquals
 
 class JvmDeviceInfoTest {
@@ -38,4 +38,14 @@ class JvmDeviceInfoTest {
         file.writeText(Json.encodeToString(DeviceInfo.serializer(), device))
         assertEquals(device, file.loadAsDeviceInfo())
     }
+
+
+    // TODO: 2022/10/19 move this to common test when Kotlin supports loading resources in commonMain
+    @Test
+    fun `can deserialize legacy versions before 2_9_0`() {
+        DeviceInfoManager.deserialize(
+            this::class.java.classLoader.getResourceAsStream("device/legacy-device-info-1.json")!!
+                .use { it.readBytes().decodeToString() })
+    }
+
 }
\ No newline at end of file