apache/cassandra · error · InvalidClassException
Event class must be of type DiagnosticEvent
Error message
Event class must be of type DiagnosticEvent
What it means
After loading a Cassandra-namespaced class, getEventClass verifies it extends DiagnosticEvent. If not, it throws InvalidClassException("Event class must be of type DiagnosticEvent") because diagnostic persistence can only store event objects deriving from DiagnosticEvent.
Solutions
- Pass a class that extends org.apache.cassandra.diag.DiagnosticEvent (see DiagnosticEventService registered events)
- Check with javap or IDE that the target class inherits from DiagnosticEvent
- Update the class name to the current one after Cassandra upgrades
- Use org.apache.cassandra.diag.DiagnosticEventService.getEventClasses() equivalents to enumerate valid events
Example fix
// before
bean.enableEventPersistence("org.apache.cassandra.diag.DiagnosticEventService");
// after
bean.enableEventPersistence("org.apache.cassandra.diag.DiagnosticEvent"); // must be a DiagnosticEvent subtype
bean.enableEventPersistence("org.apache.cassandra.db.commitlog.CommitLogEvent"); Defensive patterns
Strategy: type-guard
Validate before calling
Class<?> c = Class.forName(name, false, loader);
if (!DiagnosticEvent.class.isAssignableFrom(c))
throw new IllegalArgumentException(name + " is not a DiagnosticEvent"); Type guard
boolean isDiagnosticEvent(String name) {
try { return DiagnosticEvent.class.isAssignableFrom(Class.forName(name, false, loader)); }
catch (ClassNotFoundException e) { return false; }
} Try / catch
try {
bean.enableEventPersistence(eventClazz);
} catch (InvalidClassException e) {
// resolve to a class extending org.apache.cassandra.diag.DiagnosticEvent
} Prevention
- Only pass concrete event classes registered with DiagnosticEventService
- Validate inheritance from DiagnosticEvent before enabling persistence
- Track class renames across Cassandra upgrades
When it happens
Trigger: Calling enableEventPersistence/getEvents/disableEventPersistence with an eventClazz that resolves to a Cassandra class but not a DiagnosticEvent subclass (e.g. passing a service or config class).
Common situations: Passing DiagnosticEventService or a management class instead of a concrete event class; renamed/refactored event hierarchy after upgrade; copy-paste of class names from unrelated packages.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Not a Cassandra event class:
- Addresses differ: !=
- Cannot allocated space for a heap dump snapshot. There are…
- Cannot assign value to of type
- Cannot assign value to of type
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/8d97aa74505adb48.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/diag/DiagnosticEventPersistence.java:142
Class<? extends DiagnosticEvent> cls = event.getClass();
logger.trace("Persisting received {} event", cls.getName());
DiagnosticEventStore<Long> store = getStore(cls);
store.store(event);
LastEventIdBroadcaster.instance().setLastEventId(event.getClass().getName(), store.getLastEventId());
}
@SuppressWarnings("unchecked")
private Class<DiagnosticEvent> getEventClass(String eventClazz) throws ClassNotFoundException, InvalidClassException
{
// get class by eventClazz argument name
// restrict class loading for security reasons
if (!eventClazz.startsWith("org.apache.cassandra."))
throw new RuntimeException("Not a Cassandra event class: " + eventClazz);
Class<?> clazz = Class.forName(eventClazz, false, DiagnosticEventPersistence.class.getClassLoader());
if (!(DiagnosticEvent.class.isAssignableFrom(clazz)))
throw new InvalidClassException("Event class must be of type DiagnosticEvent");
return (Class<DiagnosticEvent>) clazz.asSubclass(DiagnosticEvent.class);
}
private DiagnosticEventStore<Long> getStore(Class cls)
{
return stores.computeIfAbsent(cls, (storeKey) -> new DiagnosticEventMemoryStore());
}
}
View on GitHub (pinned to 88fd0f6a0e)