{"record":{"id":"0a07f480dbc75d3d","repo":"apache/cassandra","slug":"can-t-enable-audit-log-archiving-via-nodetool-unle","errorCode":null,"errorMessage":"Can't enable audit log archiving via nodetool unless audit_logging_options.allow_nodetool_archive_command is set to true","messagePattern":"Can't enable audit log archiving via nodetool unless audit_logging_options\\.allow_nodetool_archive_command is set to true","errorType":"exception","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/StorageService.java","lineNumber":5129,"sourceCode":"                       maxArchiveRetries, block, rollCycle, maxLogSize, maxQueueWeight, archiveCommand);\n    }\n\n    /** @deprecated See CASSANDRA-16725 */\n    @Deprecated(since = \"4.1\")\n    public void enableAuditLog(String loggerName, Map<String, String> parameters, String includedKeyspaces, String excludedKeyspaces, String includedCategories, String excludedCategories,\n                               String includedUsers, String excludedUsers) throws ConfigurationException, IllegalStateException\n    {\n        enableAuditLog(loggerName, parameters, includedKeyspaces, excludedKeyspaces, includedCategories, excludedCategories, includedUsers, excludedUsers,\n                       Integer.MIN_VALUE, null, null, Long.MIN_VALUE, Integer.MIN_VALUE, null);\n    }\n\n    public void enableAuditLog(String loggerName, Map<String, String> parameters, String includedKeyspaces, String excludedKeyspaces, String includedCategories, String excludedCategories,\n                               String includedUsers, String excludedUsers, Integer maxArchiveRetries, Boolean block, String rollCycle,\n                               Long maxLogSize, Integer maxQueueWeight, String archiveCommand) throws IllegalStateException\n    {\n        AuditLogOptions auditOptions = DatabaseDescriptor.getAuditLoggingOptions();\n        if (archiveCommand != null && !auditOptions.allow_nodetool_archive_command)\n            throw new ConfigurationException(\"Can't enable audit log archiving via nodetool unless audit_logging_options.allow_nodetool_archive_command is set to true\");\n\n        final AuditLogOptions options = new AuditLogOptions.Builder(auditOptions)\n                                        .withEnabled(true)\n                                        .withLogger(loggerName, parameters)\n                                        .withIncludedKeyspaces(includedKeyspaces)\n                                        .withExcludedKeyspaces(excludedKeyspaces)\n                                        .withIncludedCategories(includedCategories)\n                                        .withExcludedCategories(excludedCategories)\n                                        .withIncludedUsers(includedUsers)\n                                        .withExcludedUsers(excludedUsers)\n                                        .withMaxArchiveRetries(maxArchiveRetries)\n                                        .withBlock(block)\n                                        .withRollCycle(rollCycle)\n                                        .withMaxLogSize(maxLogSize)\n                                        .withMaxQueueWeight(maxQueueWeight)\n                                        .withArchiveCommand(archiveCommand)\n                                        .build();\n","sourceCodeStart":5111,"sourceCodeEnd":5147,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/StorageService.java#L5111-L5147","documentation":"StorageService.enableAuditLog() allows an archiveCommand to be supplied via nodetool/JMX, but for security reasons this is blocked unless the cassandra.yaml option audit_logging_options.allow_nodetool_archive_command is explicitly true. A ConfigurationException is thrown when an archive command is passed while the flag is disabled.","triggerScenarios":"Calling enableAuditLog(..., archiveCommand=<cmd>) with a non-null archiveCommand while allow_nodetool_archive_command is false (the default) in cassandra.yaml.","commonSituations":"Operators enabling audit log archiving at runtime via nodetool enableauditlog --archive-command; hardened clusters where the flag is deliberately left off; scripts copied from environments where the flag was enabled.","solutions":["Set audit_logging_options.allow_nodetool_archive_command: true in cassandra.yaml and restart the node.","Omit the archiveCommand parameter and rely on the pre-configured archive_command from cassandra.yaml.","If archiving is managed externally (e.g., log shipping), drop the archive command from the call entirely."],"exampleFix":"// before (cassandra.yaml)\naudit_logging_options:\n  enabled: false\n// after (cassandra.yaml)\naudit_logging_options:\n  allow_nodetool_archive_command: true\n// then restart and run nodetool enableauditlog --archive-command <cmd>","handlingStrategy":"validation","validationCode":"AuditLogOptions o = DatabaseDescriptor.getAuditLoggingOptions();\nif (archiveCommand != null && !o.allow_nodetool_archive_command)\n    throw new IllegalArgumentException(\"set audit_logging_options.allow_nodetool_archive_command: true first\");","typeGuard":null,"tryCatchPattern":"try { ss.enableAuditLog(..., archiveCommand); } catch (ConfigurationException e) { log.error(\"archiving via nodetool disallowed: {}\", e.getMessage()); }","preventionTips":["Set allow_nodetool_archive_command: true in cassandra.yaml if runtime archiving is intended.","Omit archiveCommand and pre-configure it in yaml instead.","Treat nodetool-supplied archive commands as privileged/security-sensitive.","Keep archive commands out of generic automation templates for hardened clusters."],"tags":["security","configuration","audit-log","jmx"],"backgroundTag":"feature-not-enabled","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}