{"record":{"id":"8da5de09810d6c9c","repo":"apache/cassandra","slug":"unable-to-write-to-denylisted-partition-0x-s-in","errorCode":null,"errorMessage":"Unable to write to denylisted partition [0x%s] in %s/%s","messagePattern":"Unable to write to denylisted partition \\[0x(.+?)\\] in (.+?)/(.+?)","errorType":"exception","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/StorageProxy.java","lineNumber":1244,"sourceCode":"                                          ConsistencyLevel consistencyLevel,\n                                          boolean mutateAtomically,\n                                          Dispatcher.RequestTime requestTime,\n                                          PreserveTimestamp preserveTimestamps)\n    throws WriteTimeoutException, WriteFailureException, UnavailableException, OverloadedException, InvalidRequestException\n    {\n        if (DatabaseDescriptor.getPartitionDenylistEnabled() && DatabaseDescriptor.getDenylistWritesEnabled())\n        {\n            for (final IMutation mutation : mutations)\n            {\n                for (final TableId tid : mutation.getTableIds())\n                {\n                    if (!partitionDenylist.isKeyPermitted(tid, mutation.key().getKey()))\n                    {\n                        denylistMetrics.incrementWritesRejected();\n                        // While Schema.instance.getTableMetadata() can return a null value, in this case the isKeyPermitted\n                        // call above ensures that we cannot have a null associated tid at this point.\n                        final TableMetadata tmd = Schema.instance.getTableMetadata(tid);\n                        throw new InvalidRequestException(String.format(\"Unable to write to denylisted partition [0x%s] in %s/%s\",\n                                                                        mutation.key().toString(), tmd.keyspace, tmd.name));\n                    }\n                }\n            }\n        }\n\n        List<Mutation> augmented = TriggerExecutor.instance.execute(mutations);\n\n        String keyspaceName = mutations.iterator().next().getKeyspaceName();\n        boolean updatesView = Keyspace.open(keyspaceName)\n                              .viewManager\n                              .updatesAffectView(mutations, true);\n\n        long size = IMutation.dataSize(augmented != null ? augmented : mutations);\n        writeMetrics.mutationSize.update(size);\n        writeMetricsForLevel(consistencyLevel).mutationSize.update(size);\n        if (augmented != null || mutateAtomically || updatesView)\n            mutateAtomically(augmented != null ? augmented : (List<Mutation>)mutations, consistencyLevel, updatesView, requestTime);","sourceCodeStart":1226,"sourceCodeEnd":1262,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/StorageProxy.java#L1226-L1262","documentation":"During mutation dispatch (StorageProxy's mutates via StorageProxy/performWrite path), each mutation's partition key is checked against the partition denylist; a denied key causes the write to be rejected with an InvalidRequestException naming the denied partition and its keyspace/table. This is an operator-controlled data quarantine feature.","triggerScenarios":"Any standard (non-CAS) write (INSERT/UPDATE/DELETE/BATCH member) whose partition key is denylisted while partition_denylist_enabled and denylist_writes_enabled are true.","commonSituations":"Operator denylisted a partition during an incident (corrupt data, runaway writer) while an application keeps writing to it; denylist entries added via JMX persist while clients are unaware.","solutions":["Remove the partition from the denylist via the denylist mbean/tooling once the issue is resolved.","Change the application to stop writing to the denied partition key.","Set denylist_writes_enabled=false in cassandra.yaml if writes should be allowed while reads remain denied.","Confirm with the cluster operator that the denylist entry is intentional before working around it."],"exampleFix":"// before\nsession.execute(\"INSERT INTO flagged (k, v) VALUES (?, ?)\", badKey, v); // InvalidRequestException\n// after: operator removes key from denylist (nodetool/jmx), then retry the write\nsession.execute(\"INSERT INTO flagged (k, v) VALUES (?, ?)\", badKey, v);","handlingStrategy":"validation","validationCode":"// application-side denylist mirror\nif (denylistCache.contains(partitionKey)) {\n    throw new IllegalArgumentException(\"partition \" + partitionKey + \" is denylisted; refusing write\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    session.execute(write);\n} catch (InvalidRequestException e) {\n    if (e.getMessage().contains(\"denylisted partition\")) {\n        // quarantine locally, alert ops, do not retry until entry removed\n    }\n}","preventionTips":["Sync the denylist state into the app (periodic JMX poll) to pre-filter writes.","Alert on denylistMetrics.writesRejected.","Coordinate denylist changes with application owners."],"tags":["denylist","write-rejected","invalid-request","storage-proxy"],"backgroundTag":"permission-denied","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"}