apache/flink · error · KryoException
Error during Java serialization.
Error message
Error during Java serialization.
What it means
JavaSerializer is a Kryo serializer shim that delegates to Java's native ObjectOutputStream. On write() it lazily creates an ObjectOutputStream wrapped over Kryo's Output (cached in the Kryo graph context) and calls writeObject(o). Any failure from Java serialization — most commonly the object graph containing a non-Serializable element, or a writeObject method throwing — surfaces as a KryoException saying 'Error during Java serialization.'.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/kryo/JavaSerializer.java:63
*/
public class JavaSerializer<T> extends Serializer<T> {
public JavaSerializer() {}
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public void write(Kryo kryo, Output output, T o) {
try {
ObjectMap graphContext = kryo.getGraphContext();
ObjectOutputStream objectStream = (ObjectOutputStream) graphContext.get(this);
if (objectStream == null) {
objectStream = new ObjectOutputStream(output);
graphContext.put(this, objectStream);
}
objectStream.writeObject(o);
objectStream.flush();
} catch (Exception ex) {
throw new KryoException("Error during Java serialization.", ex);
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public T read(Kryo kryo, Input input, Class aClass) {
try {
ObjectMap graphContext = kryo.getGraphContext();
ObjectInputStream objectStream = (ObjectInputStream) graphContext.get(this);
if (objectStream == null) {
// make sure we use Kryo's classloader
objectStream =
new InstantiationUtil.ClassLoaderObjectInputStream(
input, kryo.getClassLoader());
graphContext.put(this, objectStream);
}
return (T) objectStream.readObject();
} catch (Exception ex) {View on GitHub (pinned to 2f3c205e92)
Solutions
- Make the offending class and every referenced field implement java.io.Serializable (mark non-data fields transient).
- Register a proper Kryo serializer for the problematic type (KryoSerializationSchema / env.registerTypeWithKryo or Serializers.registerSerializer) so JavaSerializer is not used.
- Inspect the chained cause in the KryoException (NotSerializableException names the first non-serializable class) and fix that specific field.
- For fields that cannot be serialized, restructure them as transient plus re-derivation on readObject, or use a custom Kryo Serializer that writes only the logical state.
Example fix
// before
public class JobContext {
private Connection conn; // not serializable -> JavaSerializer fails
}
// after
public class JobContext implements java.io.Serializable {
private transient Connection conn;
private String connUrl;
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
conn = connect(connUrl); // re-derive on deserialize
}
} Defensive patterns
Strategy: validation
Validate before calling
static void assertSerializable(Object sample) {
try (java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();
java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(bos)) {
oos.writeObject(sample);
} catch (java.io.IOException e) {
throw new IllegalStateException("Value fails Java serialization: " + e.getMessage(), e);
}
} Try / catch
try {
kryo.writeClassAndObject(output, record);
} catch (com.esotericsoftware.kryo.KryoException e) {
Throwable cause = e.getCause();
if (cause instanceof java.io.NotSerializableException) {
// log which class is not serializable, fix model, fail job
}
throw e;
} Prevention
- Unit-test round-trip serialization of your data types before deploying (serialize/deserialize a representative sample).
- Register Kryo serializers for third-party types instead of letting them fall through to JavaSerializer.
- Mark infrastructure fields (connections, threads, streams) transient.
When it happens
Trigger: Kryo serializing an object with JavaSerializer (e.g. registered via Serializers.registerSerWithKryo or a type falling back to JavaSerializer) where the object or a nested field is not java.io.Serializable; a custom writeObject/ObjectOutputStream putFields mismatch; a field's type changing incompatibly between write and read; stream corruption from mixed serializers.
Common situations: Classes used in Flink data streams or in Kryo-serialized state that implement Serializable only partially (fields of non-serializable types like Thread, InputStream, or third-party objects without a Kryo serializer registered); upgrading a class and restoring old state; closures capturing non-serializable resources.
Related errors
- Error during Java deserialization.
- The Kryo Output still contains data from a previous serializ
- Could not clone serializer instance of class {className}
- Failed to serialize value '{value}'
- Cannot register null class or serializer.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/7010aca030091d11.
Report an issue: GitHub.