{"record":{"id":"d353ad2a3194003f","repo":"apache/cassandra","slug":"counter-operations-are-inherently-non-serializable","errorCode":null,"errorMessage":"Counter operations are inherently non-serializable","messagePattern":"Counter operations are inherently non-serializable","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/ConsistencyLevel.java","lineNumber":283,"sourceCode":"        switch (this)\n        {\n            case SERIAL:\n            case UNSAFE_DELAY_SERIAL:\n            case LOCAL_SERIAL:\n            case UNSAFE_DELAY_LOCAL_SERIAL:\n                return true;\n            default:\n                return false;\n        }\n    }\n\n    public void validateCounterForWrite(TableMetadata metadata) throws InvalidRequestException\n    {\n        if (this == ConsistencyLevel.ANY)\n            throw new InvalidRequestException(\"Consistency level ANY is not yet supported for counter table \" + metadata.name);\n\n        if (isSerialConsistency())\n            throw new InvalidRequestException(\"Counter operations are inherently non-serializable\");\n    }\n\n    /**\n     * With a replication factor greater than one, reads that contact more than one replica will require \n     * reconciliation of the individual replica results at the coordinator.\n     *\n     * @return true if reads at this consistency level require merging at the coordinator\n     */\n    public boolean needsReconciliation()\n    {\n        return this != ConsistencyLevel.ONE && this != ConsistencyLevel.LOCAL_ONE && this != ConsistencyLevel.NODE_LOCAL;\n    }\n\n    private void requireNetworkTopologyStrategy(AbstractReplicationStrategy replicationStrategy) throws InvalidRequestException\n    {\n        if (!(replicationStrategy instanceof NetworkTopologyStrategy))\n            throw new InvalidRequestException(String.format(\"consistency level %s not compatible with replication strategy (%s)\",\n                                                            this, replicationStrategy.getClass().getName()));","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/ConsistencyLevel.java#L265-L301","documentation":"Counter increments are implemented as non-commutative-safe read-modify-writes on replicas and are not coordinated through Paxos, so a serial consistency is meaningless for them. validateCounterForWrite rejects serial consistency levels on counter writes with this message.","triggerScenarios":"Executing a counter UPDATE/INSERT with consistency (or serial consistency) SERIAL or LOCAL_SERIAL, e.g. applying an application-wide serializable policy to counter tables.","commonSituations":"Global 'serializable mode' config applied to all statements; confusion between LWT-capable (non-counter) and counter tables; framework defaults propagating serial consistency.","solutions":["Remove serial consistency from counter write statements; counters are inherently not serializable.","Use regular consistency levels (QUORUM/LOCAL_QUORUM) for stronger counter write durability.","If linearizability is required, move that state to a non-counter table with LWTs, or use an external coordination service.","Scope serial-consistency configuration to LWT statements only."],"exampleFix":"// before\nstmt.setSerialConsistencyLevel(ConsistencyLevel.SERIAL); // on counter update\n// after\nstmt.setSerialConsistencyLevel(null); // use default; counters cannot be serializable\nstmt.setConsistencyLevel(ConsistencyLevel.QUORUM);","handlingStrategy":"validation","validationCode":"// Guard serial CL on counter writes\nif (isCounterTable(table) && serialCl != null)\n    throw new IllegalArgumentException(\"counters cannot use serial consistency\");","typeGuard":null,"tryCatchPattern":"catch (InvalidRequestException e) {\n    if (e.getMessage().contains(\"Counter operations are inherently non-serializable\")) {\n        statement.setSerialConsistencyLevel(null); // clear serial CL\n        statement.setConsistencyLevel(ConsistencyLevel.QUORUM);\n        retry();\n    } else throw e;\n}","preventionTips":["Apply serial-consistency settings only to LWT statements, never globally.","Treat counter tables as unsupported for linearizable semantics by design and document it.","Keep 'serializable mode' config flags scoped to non-counter entity types.","Review schema changes that introduce counter columns into LWT-heavy code paths."],"tags":["cassandra","consistency-level","counter","lwt"],"backgroundTag":"unsupported-operation","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"}