apache/beam · error · CoderException

Class is not registered

Error message

Class is not registered

What it means

Kryo with registration required throws IllegalArgumentException("Class is not registered: ...") when it encounters an unregistered class. KryoCoder detects that message prefix and rethrows it as a CoderException so users see the registration problem clearly; any other IllegalArgumentException propagates unchanged.

Solutions

  1. Register the reported class (from the message text) in your KryoRegistrar / beam KryoOptions registration list
  2. Register all nested field types, not just the top-level class
  3. Alternatively disable registrationRequired (kryo.setRegistrationRequired(false)) at the cost of serialization size/performance
  4. Use kryo.register(Class, Serializer) with a custom serializer for classes you can't modify

Example fix

// before
kryo.setRegistrationRequired(true); // MyEvent not registered
// after
kryo.setRegistrationRequired(true);
kryo.register(MyEvent.class);
kryo.register(MyEvent.Inner.class);
Defensive patterns

Strategy: validation

Validate before calling

java
// before pipeline run
kryo.register(MyEvent.class);
kryo.register(MyEvent.Inner.class); // register nested types too

Try / catch

java
try {
  coder.encode(value, out);
} catch (CoderException e) {
  if (e.getMessage().startsWith("Class is not registered")) {
    log.severe("Register this class with Kryo: " + e.getMessage());
  }
}

Prevention

When it happens

Trigger: Kryo instance configured with registrationRequired=true and the pipeline encodes an object whose class (or nested field class) was never registered via a KryoRegistrar / KryoOptions registration list.

Common situations: Adding a new event type to the pipeline without adding it to the Kryo registrations; nested types inside a registered class; lambda/anonymous class fields; upgrade changing generated class names (Avro/protobuf classes).

Related errors


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

Appendix: source

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

      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")
      final T instance = (T) kryoState.getKryo().readClassAndObject(inputChunked);
      return instance;
    } catch (KryoException e) {
      throw new CoderException("Cannot decode object from input stream.", e);
    }

View on GitHub (pinned to 12126d8942)