apache/cassandra · error · IllegalStateException
There are multiple appenders of class
Error message
There are multiple appenders of class %s of names %s. There is only one appender of such class allowed.
What it means
At startup Cassandra checks the logback configuration and enforces that at most one appender of each virtual-table-enabled appender class exists; a second appender of the same class would make the vtable (system_logs / system_sessions) ambiguous. It throws IllegalStateException naming the class and the duplicate appender names.
Solutions
- Edit conf/logback.xml and remove or merge one of the duplicate appenders of that class so only one remains.
- Give the second output a different appender class (e.g. FILE vs the vtable appender class) instead of a second instance of the same class.
- Check overridden logback files (logback-test.xml, custom -Dlogback.configurationFile) that may add the same appender again.
Example fix
// before (logback.xml) <appender name="DEBUGLOG" class="org.apache.cassandra.utils.logging.VirtualTableAppender">...</appender> <appender name="DEBUGLOG2" class="org.apache.cassandra.utils.logging.VirtualTableAppender">...</appender> // after <appender name="DEBUGLOG" class="org.apache.cassandra.utils.logging.VirtualTableAppender">...</appender>
Defensive patterns
Strategy: validation
Validate before calling
// in logback.xml: grep for duplicate appender class definitions before startup // ensure at most one <appender class="...VirtualTableAppender"> element exists
Prevention
- Audit logback.xml after upgrades for duplicate appender classes.
- Attach one vtable appender to a dedicated logger rather than duplicating it per level.
- Check all config sources (logback-test.xml, -Dlogback.configurationFile overrides).
When it happens
Trigger: logback.xml defines two <appender> elements whose class is the same virtual-table-enabled appender class (e.g. two instances of VirtualTableAppender / fixed-schema appender attached to different or the same loggers).
Common situations: Editing logback.xml to add a file appender while keeping an existing appender of the same class; merging config snippets during upgrades; operator copies of logback.xml that duplicate appenders for different log levels.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- You are using Cassandra with an unsupported deployment. The…
- Already logging to
- Can not initialize CMS without any seeds
- Cannot find configured row cache provider class
- Cannot locate . If this is a local file, please confirm…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/07a5c294643e98e6.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/utils/logging/LogbackLoggingSupport.java:186
{
int count = 0;
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
List<String> virtualAppenderNames = new ArrayList<>();
for (Logger logBackLogger : lc.getLoggerList())
{
for (Iterator<Appender<ILoggingEvent>> iterator = logBackLogger.iteratorForAppenders(); iterator.hasNext();)
{
Appender<?> appender = iterator.next();
if (appenderClass.isAssignableFrom(appender.getClass()))
{
virtualAppenderNames.add(appender.getName());
count += 1;
}
}
}
if (count > 1)
throw new IllegalStateException(String.format("There are multiple appenders of class %s of names %s. There is only one appender of such class allowed.",
appenderClass.getName(), String.join(",", virtualAppenderNames)));
}
private boolean hasAppenders(Logger logBackLogger)
{
Iterator<Appender<ILoggingEvent>> it = logBackLogger.iteratorForAppenders();
return it.hasNext();
}
/**
* The purpose of this class is to prevent logback from checking for config file change,
* if the current thread is executing a sandboxed thread to avoid {@link AccessControlException}s.
*
* This is obsolete with logback versions that replaced {@link ReconfigureOnChangeFilter}
* with {@link ch.qos.logback.classic.joran.ReconfigureOnChangeTask} (at least logback since 1.2.3).
*/
private static class SMAwareReconfigureOnChangeFilter extends ReconfigureOnChangeFilter
{View on GitHub (pinned to 88fd0f6a0e)