apache/cassandra · error · RuntimeException
Not a Cassandra event class:
Error message
Not a Cassandra event class:
What it means
DiagnosticEventPersistence.getEventClass restricts class loading to org.apache.cassandra.* event classes for security reasons. A RuntimeException is thrown when the supplied event class name is outside that namespace, preventing arbitrary class loading via JMX/diagnostic APIs.
Solutions
- Use the correct Cassandra event class, e.g. org.apache.cassandra.diag.EventListener or one of the *DiagnosticEventService event types
- Ensure the class name starts with org.apache.cassandra.
- Consult org.apache.cassandra.diag.DiagnosticEventService for the list of valid event classes
- If a custom event is needed, it must live under the org.apache.cassandra package (internal builds only)
Example fix
// before
bean.enableEventPersistence("com.example.MyEvent");
// after
bean.enableEventPersistence("org.apache.cassandra.db.commitlog.CommitLogChronicleEvent"); Defensive patterns
Strategy: validation
Validate before calling
// reject non-Cassandra class names before calling the JMX operation
if (!eventClazz.startsWith("org.apache.cassandra."))
throw new IllegalArgumentException("event class must be in org.apache.cassandra namespace"); Try / catch
try {
bean.enableEventPersistence(eventClazz);
} catch (RuntimeException e) {
if (e.getMessage().startsWith("Not a Cassandra event class")) {
// fix the fully-qualified class name to org.apache.cassandra.*
}
} Prevention
- Always pass fully-qualified org.apache.cassandra.* event class names
- Keep event class name constants centralized in config, not ad-hoc strings
- Re-check class names after Cassandra upgrades
When it happens
Trigger: Calling enableEventPersistence/getEvents/disableEventPersistence with an eventClazz string not starting with "org.apache.cassandra."
Common situations: Typo in package name; passing a fully-qualified class of a third-party or application event; using an old class name after a package refactor.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Event class must be of type DiagnosticEvent
- Access denied
- Access denied
- Access Denied
- access denied: + MODIFY_THREAD_PERMISSION
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/7920d5e447a518b9.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/diag/DiagnosticEventPersistence.java:137
}
}
private void onEvent(DiagnosticEvent event)
{
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)