apache/beam · error · CoderException

Cannot encode given object of type [<value.getClass()>].

Error message

Cannot encode given object of type [<value.getClass()>].

What it means

When Kryo throws KryoException during writeClassAndObject, KryoCoder.encode() resets the output and rethrows a CoderException naming the Java class that failed to serialize, chaining the KryoException. EOFException causes are rethrown as-is since they indicate stream truncation, not encoding failure.

Solutions

  1. Read the chained KryoException cause to find the offending field/class
  2. Register the class with a KryoRegistrar or make it Kryo-serializable (no-arg constructor, no transient-unfriendly fields)
  3. Mark unserializable fields transient or exclude them via a custom Kryo FieldSerializer
  4. Replace unserializable field types with plain data (e.g. byte[] instead of InputStream)

Example fix

// before
public class Event { private InputStream data; }
// after
public class Event { private transient InputStream data; private byte[] dataBytes; }
Defensive patterns

Strategy: try-catch

Validate before calling

java
// smoke-test serialization of representative objects before launching
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
  coder.encode(sampleValue, bos);
} catch (Exception e) { throw new IllegalStateException("Unencodable sample: " + sampleValue.getClass(), e); }

Try / catch

java
try {
  coder.encode(value, out);
} catch (CoderException e) {
  if (e.getMessage().startsWith("Cannot encode given object of type")) {
    log.severe("Kryo cannot serialize " + e.getCause());
  }
}

Prevention

When it happens

Trigger: Serializing an object graph containing classes Kryo can't handle — non-serializable fields (streams, connections), classes with broken no-arg constructors, or deeply circular references exceeding Kryo limits.

Common situations: DoFn output types holding an InputStream/Socket/Logger; classes without no-arg constructors (Kryo's default instantiation); objects from third-party libs never designed for serialization; JDK version changes altering internal classes.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/bbc2f692bcbdd582. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/extensions/kryo/src/main/java/org/apache/beam/sdk/extensions/kryo/KryoCoder.java:209

  @Override
  public void encode(T value, OutputStream outStream) throws IOException {
    final KryoState kryoState = KryoState.get(this);
    if (value == null) {
      throw new CoderException("Cannot encode a null value.");
    }
    final OutputChunked outputChunked = kryoState.getOutputChunked();
    outputChunked.setOutputStream(outStream);
    try {
      kryoState.getKryo().writeClassAndObject(outputChunked, value);
      outputChunked.endChunk();
      outputChunked.flush();
    } catch (KryoException e) {
      outputChunked.reset();
      if (e.getCause() instanceof EOFException) {
        throw (EOFException) e.getCause();
      }
      throw new CoderException("Cannot encode given object of type [" + value.getClass() + "].", e);
    } catch (IllegalArgumentException e) {
      String message = e.getMessage();
      if (message != null) {
        if (message.startsWith("Class is not registered")) {
          throw new CoderException(message);
        }
      }
      throw e;
    }
  }

  @Override
  public T decode(InputStream inStream) throws IOException {
    final KryoState kryoState = KryoState.get(this);
    final InputChunked inputChunked = kryoState.getInputChunked();
    inputChunked.setInputStream(inStream);
    try {
      @SuppressWarnings("unchecked")

View on GitHub (pinned to 12126d8942)