ClassCastException thrown from unused Retrofit services with R8
Author: grandstaishCreated Apr 30, 2024Updated Jul 16, 2026
Bit of an edge case here—but if all of the functions in a Retrofit interface are unused, R8 will strip them. This causes the following Proguard rule to miss: https://github.com/square/retrofit/blob/dfdad425e9d1c47dbce335c9808c75c72ef912cc/retrofit/src/main/resources/META-INF/proguard/retrofit2.pro#L31
Then once you try to instantiate the stripped service class, you get a fairly nondescript ClassCastException from Retrofit. E.g.:
Caused by: java.lang.ClassCastException
at androidx.appcompat.app.ToolbarActionBar$$ExternalSyntheticThrowCCEIfNotNull0.m(:0)Replacing the referenced rule with the following one fixes the issue for us:
-if interface *
-keepclasseswithmembers,allowobfuscation interface <1> {
@retrofit2.http.* <methods>;
}(Source: here)
Note: I barely know how to proguard, so this definitely requires some scrutiny. Raising issue here for visibility.
Source: lysine-dev/retrofit