{"record":{"id":"0608678de52c0d3a","repo":"apache/cassandra","slug":"triggers-are-present-but-triggerspolicy-forbidden","errorCode":null,"errorMessage":"Triggers are present but TriggersPolicy.forbidden is configured. Failing query that would execute triggers: %s","messagePattern":"Triggers are present but TriggersPolicy\\.forbidden is configured\\. Failing query that would execute triggers: (.+?)","errorType":"exception","errorClass":"TriggerDisabledException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/triggers/TriggerExecutor.java","lineNumber":249,"sourceCode":"\n    /**\n     * Switch class loader before using the triggers for the column family, if\n     * not loaded them with the custom class loader.\n     */\n    private List<Mutation> executeInternal(PartitionUpdate update)\n    {\n        Triggers triggers = update.metadata().triggers;\n        if (triggers.isEmpty())\n            return null;\n        Config.TriggersPolicy policy = DatabaseDescriptor.getTriggersPolicy();\n        if (policy == Config.TriggersPolicy.disabled)\n        {\n            skippedTriggerLogger.warn(\"Skipping execution of triggers due to configuration TriggersPolicy.disabled: {}\", triggers);\n            return null;\n        }\n        if (policy == Config.TriggersPolicy.forbidden)\n        {\n            throw new TriggerDisabledException(String.format(\"Triggers are present but TriggersPolicy.forbidden is configured. Failing query that would execute triggers: %s\", triggers));\n        }\n        List<Mutation> tmutations = Lists.newLinkedList();\n        Thread.currentThread().setContextClassLoader(customClassLoader);\n        String triggerClass = \"\";\n        try\n        {\n            for (TriggerMetadata td : triggers)\n            {\n                ITrigger trigger = cachedTriggers.get(td.classOption);\n                triggerClass = td.classOption;\n                if (trigger == null)\n                {\n                    trigger = loadTriggerInstance(td.classOption);\n                    cachedTriggers.put(td.classOption, trigger);\n                }\n                Collection<Mutation> temp = trigger.augment(update);\n                if (temp != null)\n                    tmutations.addAll(temp);","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/triggers/TriggerExecutor.java#L231-L267","documentation":"When cassandra.yaml sets triggers_policy: forbidden, any statement that would execute triggers (a table with triggers present) is failed outright with TriggerDisabledException, embedding the list of triggers that would have run. Unlike the 'disabled' policy (which silently skips triggers and logs a warning), 'forbidden' treats executing such a statement as an error to surface misconfiguration.","triggerScenarios":"A write (INSERT/UPDATE/BATCH) touches a table that has triggers defined while Config.TriggersPolicy is set to forbidden in cassandra.yaml; triggered via TriggerExecutor.executeInternal from intermediate/augmentations paths.","commonSituations":"Operators hardened a cluster by setting triggers_policy: forbidden but applications still rely on legacy triggers; environment/config drift between dev (default/disabled) and prod (forbidden); upgrading to a version where TriggersPolicy was introduced with forbidden as the chosen policy.","solutions":["Remove the triggers from the affected tables (DROP TRIGGER) since policy forbids them","Change cassandra.yaml to triggers_policy: enabled (or disabled) and restart the node if triggers are still required","Update the application to stop relying on triggers and perform the equivalent writes explicitly"],"exampleFix":"// before (cassandra.yaml)\ntriggers_policy: forbidden\n// after\ntriggers_policy: enabled","handlingStrategy":"try-catch","validationCode":"// before writes: check cluster policy and table triggers\nString policy = config.get('triggers_policy');\nboolean hasTriggers = schema.getTriggers(table).size() > 0;\nif ('forbidden'.equals(policy) && hasTriggers) throw new IllegalStateException('Writes to ' + table + ' will fail: triggers_policy=forbidden');","typeGuard":null,"tryCatchPattern":"catch TriggerDisabledException (or InvalidRequestException wrapping it), then retry after dropping the trigger or changing policy","preventionTips":["Keep triggers_policy consistent across environments","Audit tables for triggers before setting policy to forbidden","Plan trigger removal before hardening cluster config"],"tags":["triggers","configuration","policy","invalid-request"],"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"}