eclipse-vertx/vert.x · error · RuntimeException

Class not allowed:

Error message

Class not allowed: 

What it means

ClusterSerializableCodec decodes a ClusterSerializable payload by reading the class name from the wire and only instantiates classes the CodecManager's acceptClusterSerializable whitelist allows. It throws this RuntimeException when the class name embedded in the received buffer is not on the allowed list, mitigating arbitrary-class deserialization from the network.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/eventbus/impl/codecs/ClusterSerializableCodec.java:44

  public ClusterSerializableCodec(CodecManager codecManager) {
    this.codecManager = codecManager;
  }

  @Override
  public void encodeToWire(Buffer buffer, ClusterSerializable obj) {
    byte[] classNameBytes = obj.getClass().getName().getBytes(CharsetUtil.UTF_8);
    buffer.appendInt(classNameBytes.length).appendBytes(classNameBytes);
    obj.writeToBuffer(buffer);
  }

  @Override
  public ClusterSerializable decodeFromWire(int pos, Buffer buffer) {
    int len = buffer.getInt(pos);
    pos += 4;
    byte[] classNameBytes = buffer.getBytes(pos, pos + len);
    String className = new String(classNameBytes, CharsetUtil.UTF_8);
    if (!codecManager.acceptClusterSerializable(className)) {
      throw new RuntimeException("Class not allowed: " + className);
    }
    pos += len;
    ClusterSerializable clusterSerializable;
    try {
      Class<?> clazz = getClassLoader().loadClass(className);
      clusterSerializable = (ClusterSerializable) clazz.getDeclaredConstructor().newInstance();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    clusterSerializable.readFromBuffer(pos, buffer);
    return clusterSerializable;
  }

  private static ClassLoader getClassLoader() {
    ClassLoader tccl = Thread.currentThread().getContextClassLoader();
    return tccl != null ? tccl : ClusterSerializableCodec.class.getClassLoader();
  }

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Register the class in the receiving node's allowed ClusterSerializable classes (setAllowClusterSerializableClasses / matching configuration).
  2. Ensure both sender and receiver have the same class on the classpath and the same codec configuration.
  3. Verify cluster nodes run identical versions of your message-model library.
  4. Check acceptClusterSerializable configuration in EventBusOptions on all nodes.

Example fix

// before
// receiving node lacks the class in the allowlist
// after
new EventBusOptions().setAllowedClusterSerializableClasses(Set.of("com.myapp.MyPayload")); // configured consistently on all nodes
Defensive patterns

Strategy: try-catch

Validate before calling

// on the receiving node, verify before deploy
if (!eventBusOptionsAllowedClusterSerializable.contains("com.myapp.MyPayload")) {
  throw new IllegalStateException("MyPayload not in cluster-serializable allowlist");
}

Try / catch

try {
  delivery.completion().await();
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Class not allowed:")) {
    // sync allowlist/codecs between cluster nodes and resend
  }
}

Prevention

When it happens

Trigger: A clustered event bus message carries a ClusterSerializable whose class name is not in the allowedClusterSerializable list on the receiving node (send-side class registered only on sender).

Common situations: Asymmetric deployments where one node has a message class and another doesn't; classes not added to the cluster-serializable allowlist via EventBusOptions/CodecManager configuration; security features filtering deserialization targets.

Related errors


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/ecd3e6b1d69a7c85. Report an issue: GitHub.