{"record":{"id":"07a5c294643e98e6","repo":"apache/cassandra","slug":"there-are-multiple-appenders-of-class-s-of-names","errorCode":null,"errorMessage":"There are multiple appenders of class %s of names %s. There is only one appender of such class allowed.","messagePattern":"There are multiple appenders of class (.+?) of names (.+?)\\. There is only one appender of such class allowed\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/utils/logging/LogbackLoggingSupport.java","lineNumber":186,"sourceCode":"    {\n        int count = 0;\n        LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();\n        List<String> virtualAppenderNames = new ArrayList<>();\n        for (Logger logBackLogger : lc.getLoggerList())\n        {\n            for (Iterator<Appender<ILoggingEvent>> iterator = logBackLogger.iteratorForAppenders(); iterator.hasNext();)\n            {\n                Appender<?> appender = iterator.next();\n                if (appenderClass.isAssignableFrom(appender.getClass()))\n                {\n                    virtualAppenderNames.add(appender.getName());\n                    count += 1;\n                }\n            }\n        }\n\n        if (count > 1)\n            throw new IllegalStateException(String.format(\"There are multiple appenders of class %s of names %s. There is only one appender of such class allowed.\",\n                                                          appenderClass.getName(), String.join(\",\", virtualAppenderNames)));\n    }\n\n    private boolean hasAppenders(Logger logBackLogger)\n    {\n        Iterator<Appender<ILoggingEvent>> it = logBackLogger.iteratorForAppenders();\n        return it.hasNext();\n    }\n\n    /**\n     * The purpose of this class is to prevent logback from checking for config file change,\n     * if the current thread is executing a sandboxed thread to avoid {@link AccessControlException}s.\n     *\n     * This is obsolete with logback versions that replaced {@link ReconfigureOnChangeFilter}\n     * with {@link ch.qos.logback.classic.joran.ReconfigureOnChangeTask} (at least logback since 1.2.3).\n     */\n    private static class SMAwareReconfigureOnChangeFilter extends ReconfigureOnChangeFilter\n    {","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/utils/logging/LogbackLoggingSupport.java#L168-L204","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before (logback.xml)\n<appender name=\"DEBUGLOG\" class=\"org.apache.cassandra.utils.logging.VirtualTableAppender\">...</appender>\n<appender name=\"DEBUGLOG2\" class=\"org.apache.cassandra.utils.logging.VirtualTableAppender\">...</appender>\n// after\n<appender name=\"DEBUGLOG\" class=\"org.apache.cassandra.utils.logging.VirtualTableAppender\">...</appender>","handlingStrategy":"validation","validationCode":"// in logback.xml: grep for duplicate appender class definitions before startup\n// ensure at most one <appender class=\"...VirtualTableAppender\"> element exists","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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)."],"tags":["logging","logback","configuration","startup"],"backgroundTag":"invalid-config-value","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}