{"record":{"id":"ecd3e6b1d69a7c85","repo":"eclipse-vertx/vert.x","slug":"class-not-allowed","errorCode":null,"errorMessage":"Class not allowed: ","messagePattern":"Class not allowed: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/eventbus/impl/codecs/ClusterSerializableCodec.java","lineNumber":44,"sourceCode":"  public ClusterSerializableCodec(CodecManager codecManager) {\n    this.codecManager = codecManager;\n  }\n\n  @Override\n  public void encodeToWire(Buffer buffer, ClusterSerializable obj) {\n    byte[] classNameBytes = obj.getClass().getName().getBytes(CharsetUtil.UTF_8);\n    buffer.appendInt(classNameBytes.length).appendBytes(classNameBytes);\n    obj.writeToBuffer(buffer);\n  }\n\n  @Override\n  public ClusterSerializable decodeFromWire(int pos, Buffer buffer) {\n    int len = buffer.getInt(pos);\n    pos += 4;\n    byte[] classNameBytes = buffer.getBytes(pos, pos + len);\n    String className = new String(classNameBytes, CharsetUtil.UTF_8);\n    if (!codecManager.acceptClusterSerializable(className)) {\n      throw new RuntimeException(\"Class not allowed: \" + className);\n    }\n    pos += len;\n    ClusterSerializable clusterSerializable;\n    try {\n      Class<?> clazz = getClassLoader().loadClass(className);\n      clusterSerializable = (ClusterSerializable) clazz.getDeclaredConstructor().newInstance();\n    } catch (Exception e) {\n      throw new RuntimeException(e);\n    }\n    clusterSerializable.readFromBuffer(pos, buffer);\n    return clusterSerializable;\n  }\n\n  private static ClassLoader getClassLoader() {\n    ClassLoader tccl = Thread.currentThread().getContextClassLoader();\n    return tccl != null ? tccl : ClusterSerializableCodec.class.getClassLoader();\n  }\n","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/eventbus/impl/codecs/ClusterSerializableCodec.java#L26-L62","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Register the class in the receiving node's allowed ClusterSerializable classes (setAllowClusterSerializableClasses / matching configuration).","Ensure both sender and receiver have the same class on the classpath and the same codec configuration.","Verify cluster nodes run identical versions of your message-model library.","Check acceptClusterSerializable configuration in EventBusOptions on all nodes."],"exampleFix":"// before\n// receiving node lacks the class in the allowlist\n// after\nnew EventBusOptions().setAllowedClusterSerializableClasses(Set.of(\"com.myapp.MyPayload\")); // configured consistently on all nodes","handlingStrategy":"try-catch","validationCode":"// on the receiving node, verify before deploy\nif (!eventBusOptionsAllowedClusterSerializable.contains(\"com.myapp.MyPayload\")) {\n  throw new IllegalStateException(\"MyPayload not in cluster-serializable allowlist\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  delivery.completion().await();\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Class not allowed:\")) {\n    // sync allowlist/codecs between cluster nodes and resend\n  }\n}","preventionTips":["Configure identical ClusterSerializable allowlists on every cluster node","Keep the message-model library at the same version cluster-wide","Prefer explicit MessageCodecs over wire class names for cross-node payloads"],"tags":["eventbus","codec","deserialization","security","cluster"],"backgroundTag":"class-not-found","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}