apache/flink · critical · IllegalStateException

Unable to find the class '%s' which is used to deserialize t

Error message

Unable to find the class '%s' which is used to deserialize the elements of this serializer. Were the class was moved or renamed?

What it means

IllegalStateException from AvroSerializerSnapshot.findClassOrThrow when Class.forName cannot load the Avro record class (or SpecificRecord) referenced by the restored state. The serializer snapshot stores the runtime class name; on restore it must be loadable from the user code classloader of the restored job.

Source

Thrown at flink-formats/flink-avro/src/main/java/org/apache/flink/formats/avro/typeutils/AvroSerializerSnapshot.java:236

            @SuppressWarnings("unchecked")
            SpecificData d =
                    AvroFactory.getSpecificDataForClass(
                            (Class<? extends SpecificData>) runtimeType, cl);
            return AvroFactory.extractAvroSpecificSchema(runtimeType, d);
        }
        ReflectData d = new ReflectData(cl);
        return d.getSchema(runtimeType);
    }

    @SuppressWarnings("unchecked")
    @Nonnull
    private static <T> Class<T> findClassOrThrow(
            ClassLoader userCodeClassLoader, String className) {
        try {
            Class<?> runtimeTarget = Class.forName(className, false, userCodeClassLoader);
            return (Class<T>) runtimeTarget;
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException(
                    ""
                            + "Unable to find the class '"
                            + className
                            + "' which is used to deserialize "
                            + "the elements of this serializer. "
                            + "Were the class was moved or renamed?",
                    e);
        }
    }

    @SuppressWarnings("unchecked")
    @Nonnull
    private static <T> Class<T> findClassOrFallbackToGeneric(
            ClassLoader userCodeClassLoader, String className) {
        try {
            Class<?> runtimeTarget = Class.forName(className, false, userCodeClassLoader);
            return (Class<T>) runtimeTarget;
        } catch (ClassNotFoundException e) {

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Keep the fully-qualified class name of Avro records stable across job versions (regenerate code into the same package).
  2. Repackage the jar so the record class is included on the user classpath and not shaded away.
  3. If rename is unavoidable, perform a state migration (savepoint processor API) instead of direct restore.
Defensive patterns

Strategy: validation

Validate before calling

// before restore, verify the record class is on the job classpath
Class<?> c = Class.forName("com.acme.avro.User", false, getUserClassloader());
if (!org.apache.avro.specific.SpecificRecordBase.class.isAssignableFrom(c)) {
    throw new IllegalStateException("Restored Avro class is not a SpecificRecord");
}

Try / catch

try {
    env.execute();
} catch (IllegalStateException e) {
    if (e.getMessage().contains("Unable to find the class")) {
        // class moved/missing from jar; fix packaging or class name, then restore again
        log.error("Avro record class missing on user classpath: {}", e.getCause().getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: Restoring a savepoint after the Avro generated record class was renamed, moved to another package, or removed from the job jar; running with a fat jar that shades/relocates the record class.

Common situations: Refactoring generated Avro classes between job versions; maven-shade relocation of avro generated packages; the class living in a dependency not packaged into the application jar.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/12a66f60a186b0b1. Report an issue: GitHub.