google/gson · error · JsonIOException

Abstract classes can't be instantiated! Adjust the R8 config

Error message

Abstract classes can't be instantiated! Adjust the R8 configuration or register an InstanceCreator or a TypeAdapter for this type. Class name: ${c.getName()}
See ${TroubleshootingGuide.createUrl("r8-abstract-class")}

What it means

Thrown when Gson attempts to deserialize into an abstract class and no InstanceCreator or TypeAdapter is registered. The message specifically calls out R8, which on Android can strip a class's default constructor and mark it abstract during optimization. The message includes a troubleshooting guide URL.

Source

Thrown at gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java:424

   * ObjectConstructor}, which would then choose another way of creating the object. And it supports
   * types which are only serialized but not deserialized (compared to directly throwing an
   * exception when the {@code ObjectConstructor} is requested), e.g. when the runtime type of an
   * object is inaccessible, but the compile-time type is accessible.
   */
  private static final class ThrowingObjectConstructor<T> implements ObjectConstructor<T> {
    private final String exceptionMessage;

    ThrowingObjectConstructor(String exceptionMessage) {
      this.exceptionMessage = exceptionMessage;
    }

    @Override
    public T construct() {
      // New exception is created every time to avoid keeping a reference to an exception with
      // potentially long stack trace, causing a memory leak
      // (which would happen if the exception was already created when the
      // `ThrowingObjectConstructor` is created)
      throw new JsonIOException(exceptionMessage);
    }
  }

  private static final class InstanceCreatorConstructor<T> implements ObjectConstructor<T> {
    private final InstanceCreator<T> instanceCreator;
    private final Type type;

    InstanceCreatorConstructor(InstanceCreator<T> instanceCreator, Type type) {
      this.instanceCreator = instanceCreator;
      this.type = type;
    }

    @Override
    public T construct() {
      return instanceCreator.createInstance(type);
    }
  }
}

View on GitHub (pinned to 310ac341f2)

Solutions

  1. Add R8/ProGuard keep rules: -keep class com.example.MyClass { <init>(); }
  2. Register an InstanceCreator returning a concrete subtype
  3. Register a custom TypeAdapter for the abstract type
  4. Deserialize into a concrete subclass instead

Example fix

// before - R8 strips ctor, class becomes abstract
// (no keep rule)

// after - proguard-rules.pro
-keep class com.example.MyModel { <init>(); }
Defensive patterns

Strategy: validation

Validate before calling

// Check if target is abstract before deserializing
Class<?> c = (Class<?>) targetType;
if (Modifier.isAbstract(c.getModifiers()) && !c.isArray()) {
  throw new IllegalArgumentException(
    "Cannot deserialize into abstract class " + c.getName() + "; register InstanceCreator");
}

Type guard

static boolean isR8Safe(Class<?> c) {
  return !Modifier.isAbstract(c.getModifiers())
      && c.getDeclaredConstructors().length > 0;
}

Try / catch

try {
  return gson.fromJson(json, MyAbstract.class);
} catch (JsonIOException e) {
  if (e.getMessage().startsWith("Abstract classes can't be instantiated")) {
    // add R8 keep rule or register InstanceCreator returning a concrete subtype
    throw new MyParseException("Abstract class needs InstanceCreator or R8 keep rule", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling gson.fromJson into an abstract class type without InstanceCreator/TypeAdapter; OR after R8/proguard optimization removed the no-args constructor and marked the class abstract, defeating the no-args-constructor lookup path.

Common situations: Android R8 shrinking removing constructors; deserializing into abstract base types; model classes obfuscated/shrunk without keep rules; migrating to R8 full mode.

Related errors


AI-assisted analysis of google/gson@310ac341f2 (2026-08-10). Data as JSON: /api/errors/5ed7cb2862bf2cf1. Report an issue: GitHub.