Fixing 'Serializer for class is not found' in Kotlinx Serialization

intermediate๐Ÿ“ฑ Android2026-07-07| Android Studio, Kotlin 1.5 to 2.0+, Gradle (Groovy or KTS), ProGuard/R8

Error Message

kotlinx.serialization.SerializationException: Serializer for class 'X' is not found. Mark the class as @Serializable or provide the serializer explicitly.
#Kotlin#Android#Kotlinx Serialization#Gradle#R8

The Frustrating CrashYou've built your data models and integrated kotlinx.serialization to handle your API responses. Everything looks perfect until you run Json.decodeFromString<User>(jsonString). Instead of a populated object, your app hits a wall with this exception:

kotlinx.serialization.SerializationException: Serializer for class 'User' is not found. 
Mark the class as @Serializable or provide the serializer explicitly.

This error usually pops up at runtime when the library looks for a generated $serializer companion object that doesn't exist. It can also happen at compile-time if your build environment isn't talking to the Kotlin compiler correctly.

Why Kotlinx Serialization is DifferentLegacy libraries like Gson or Jackson use reflection to peek inside classes while the app is running. Kotlinx Serialization takes a different path. It's a compiler-based engine. It relies on a specific Kotlin compiler plugin to generate serialization logic while you're building your APK. If that plugin isn't active, the @Serializable annotation is just a decorative comment that the library ignores.

Most developers run into this for one of four reasons:

  • The kotlinx-serialization compiler plugin is missing from Gradle.- You forgot the @Serializable annotation on a nested data class.- R8 (ProGuard) stripped away the generated code in your release build.- There is a version mismatch between Kotlin (e.g., 1.9.20) and the serialization library (e.g., 1.6.0).## The Step-by-Step Fix### 1. Apply the Compiler PluginAdding the runtime dependency (the implementation line) isn't enough. You must tell the Kotlin compiler to generate the extra code. Open your app-level build.gradle file and ensure the plugin is registered. For Groovy (build.gradle):
plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    // The essential missing piece:
    id 'org.jetbrains.kotlin.plugin.serialization' version '1.9.22' 
}

For Kotlin DSL (build.gradle.kts):

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    // Match this version to your project's Kotlin version
    kotlin("plugin.serialization") version "1.9.22"
}

2. Double-Check Your AnnotationsEvery class involved in the serialization chain needs the annotation. If your User class contains a Address class, both need to be marked. It's a common oversight when dealing with complex, nested JSON trees.

import kotlinx.serialization.Serializable

@Serializable
data class User(
    val id: Int,
    val name: String,
    val location: Address // Address must also be @Serializable!
)

3. Configure R8 for Release BuildsDoes your app work in Debug but crash in Release? That's a classic R8 issue. The shrinker sees the generated $serializer classes as "unused" and deletes them to save space. You need to keep these classes intact.

Add these rules to your proguard-rules.pro file:

# Keep the Serializer logic for annotated classes
-keepclassmembernames class * {
    @kotlinx.serialization.Serializable *;
}

# Prevent R8 from removing the generated $serializer
-keepclassnames class kotlinx.serialization.internal.** { *; }
-keepclassmembers class * extends kotlinx.serialization.KSerializer {
    public static ** INSTANCE;
}

Pro-Tips for DebuggingAlways verify your JSON source before diving into code changes. A single missing comma or a null value in a non-nullable field can trigger misleading errors. I use the JSON Formatter & Validator on ToolCraft to check raw API strings. It quickly highlights structural mismatches that might be hiding behind a 'Serializer not found' message.

If you're working in a multi-module project, remember that the kotlin-serialization plugin is not inherited. You must apply it to every single module that contains a @Serializable class. If Module A uses a data class from Module B, and Module B doesn't have the plugin, your app will crash at runtime.

Final VerificationFollow these three steps to ensure the fix sticks:

  • Run Clean Project followed by Rebuild Project. This forces the compiler plugin to re-run.- Test the Json.decodeFromString call in Debug mode first.- Build a Release APK and test it on a physical device. This confirms your ProGuard rules are actually working.

Related Error Notes