eclipse-vertx/vert.x · error · InvalidClassException
Class not allowed:
Error message
Class not allowed:
What it means
SerializableCodec uses an ObjectInputStream subclass whose resolveClass validates every class encountered during Java deserialization against CodecManager.acceptSerializable. It throws InvalidClassException("Class not allowed: ...") when the stream references a class not on the allowlist, preventing unsafe arbitrary deserialization.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/eventbus/impl/codecs/SerializableCodec.java:70
public String name() {
return "serializable";
}
@Override
public byte systemCodecID() {
return 17;
}
private class CheckedClassNameObjectInputStream extends ObjectInputStream {
CheckedClassNameObjectInputStream(InputStream in) throws IOException {
super(in);
}
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
String name = desc.getName();
if (!codecManager.acceptSerializable(name)) {
throw new InvalidClassException("Class not allowed: " + name);
}
return super.resolveClass(desc);
}
}
}
View on GitHub (pinned to fb308bd8c3)
Solutions
- Add the offending class to the allowed serializable classes on the receiving node's EventBusOptions/codec configuration.
- Keep message payload types simple and ensure all referenced classes are whitelisted on every node.
- Switch to an explicit MessageCodec (e.g. buffer/JSON-based) instead of default Java serialization for complex types.
- Synchronize the message-model dependency version across all cluster nodes.
Example fix
// before
new EventBusOptions().setAllowedSerializableClasses(Set.of("com.myapp.A")); // B referenced inside A
// after
new EventBusOptions().setAllowedSerializableClasses(Set.of("com.myapp.A", "com.myapp.B")); Defensive patterns
Strategy: try-catch
Validate before calling
// keep an explicit allowlist in sync with your payload graph
Set<String> allowed = new EventBusOptions().getAllowedSerializableClasses(); // or your configured set
if (!allowed.contains("com.myapp.NewEmbeddedType")) {
throw new IllegalStateException("add NewEmbeddedType to the serializable allowlist");
} Try / catch
try {
bus.request("addr", payload);
} catch (Exception e) {
if (e.getCause() instanceof InvalidClassException) {
// whitelist the missing class on receiving nodes or switch to a buffer codec
}
} Prevention
- Whitelist every class reachable in serialized message graphs on all nodes
- Avoid third-party types inside Serializable message payloads
- Use a custom buffer/JSON MessageCodec instead of default Java serialization
- Keep serialization allowlist configuration in version control, shared by all services
When it happens
Trigger: A clustered event bus message with a Serializable body whose class (or a class reachable in its object graph) is missing from the allowed serializable class list on the receiving node.
Common situations: Adding a field of a new type to a message class so deserialization touches a class not whitelisted; third-party library types in message payloads; inconsistent allowlist configuration across cluster nodes.
Related errors
- Class not allowed:
- Already a codec registered with name
- Already a default codec registered for class
- Can't register a system codec
- Already started
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/b441d8d1efb6dbc5.
Report an issue: GitHub.