{"record":{"id":"1eb5c2ee7d2ad6d0","repo":"apache/cassandra","slug":"you-must-use-conditional-updates-for-serializable","errorCode":null,"errorMessage":"You must use conditional updates for serializable writes","messagePattern":"You must use conditional updates for serializable writes","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/ConsistencyLevel.java","lineNumber":237,"sourceCode":"\n    public void validateForRead() throws InvalidRequestException\n    {\n        switch (this)\n        {\n            case ANY:\n                throw new InvalidRequestException(\"ANY ConsistencyLevel is only supported for writes\");\n        }\n    }\n\n    public void validateForWrite() throws InvalidRequestException\n    {\n        switch (this)\n        {\n            case SERIAL:\n            case UNSAFE_DELAY_SERIAL:\n            case LOCAL_SERIAL:\n            case UNSAFE_DELAY_LOCAL_SERIAL:\n                throw new InvalidRequestException(\"You must use conditional updates for serializable writes\");\n        }\n    }\n\n    // This is the same than validateForWrite really, but we include a slightly different error message for SERIAL/LOCAL_SERIAL\n    public void validateForCasCommit(AbstractReplicationStrategy replicationStrategy) throws InvalidRequestException\n    {\n        switch (this)\n        {\n            case EACH_QUORUM:\n                requireNetworkTopologyStrategy(replicationStrategy);\n                break;\n            case SERIAL:\n            case UNSAFE_DELAY_SERIAL:\n            case LOCAL_SERIAL:\n            case UNSAFE_DELAY_LOCAL_SERIAL:\n                throw new InvalidRequestException(this + \" is not supported as conditional update commit consistency. Use ANY if you mean \\\"make sure it is accepted but I don't care how many replicas commit it for non-SERIAL reads\\\"\");\n        }\n    }","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/ConsistencyLevel.java#L219-L255","documentation":"SERIAL (and related) consistency levels apply only to the serial phase of lightweight-transaction (LWT) operations; they cannot be used for plain writes. validateForWrite rejects any serial-family level for a non-conditional write. A serializable write on Cassandra requires a conditional update (INSERT ... IF NOT EXISTS / UPDATE ... IF).","triggerScenarios":"Executing an unconditional INSERT/UPDATE/BATCH write with consistency SERIAL, LOCAL_SERIAL (or the UNSAFE_DELAY variants), e.g. `CONSISTENCY SERIAL;` then a plain INSERT in cqlsh.","commonSituations":"Confusion between the serial and commit consistency of LWTs; porting code from systems where serializable implies all writes; leftover CONSISTENCY SERIAL in cqlsh sessions.","solutions":["Use a conditional statement (INSERT ... IF NOT EXISTS or UPDATE ... IF <condition>) when serial consistency is required.","For plain writes, switch consistency to QUORUM/LOCAL_QUORUM/EACH_QUORUM as appropriate.","Set the serial consistency separately via the driver's serial consistency API (setSerialConsistencyLevel) rather than the write consistency.","In cqlsh, run `CONSISTENCY QUORUM;` before non-conditional writes."],"exampleFix":"// before\nsession.execute(SimpleStatement.builder(\"INSERT INTO t(k,v) VALUES (1,2)\")\n    .setConsistencyLevel(ConsistencyLevel.SERIAL).build());\n// after\nsession.execute(SimpleStatement.builder(\"INSERT INTO t(k,v) VALUES (1,2) IF NOT EXISTS\")\n    .setConsistencyLevel(ConsistencyLevel.QUORUM)\n    .setSerialConsistencyLevel(ConsistencyLevel.SERIAL).build());","handlingStrategy":"validation","validationCode":"// Client-side guard for plain writes\nif (cl == ConsistencyLevel.SERIAL || cl == ConsistencyLevel.LOCAL_SERIAL)\n    throw new IllegalArgumentException(\"serial CL requires conditional update\");","typeGuard":null,"tryCatchPattern":"catch (InvalidRequestException e) {\n    if (e.getMessage().contains(\"conditional updates\")) {\n        // either make the statement conditional or drop to QUORUM\n        statement.setConsistencyLevel(ConsistencyLevel.QUORUM);\n    } else throw e;\n}","preventionTips":["Set serial consistency only via setSerialConsistencyLevel on LWT statements.","Keep cqlsh CONSISTENCY at QUORUM for general work; use SERIAL CONSISTENCY for LWT sessions.","Document the two-level (serial vs commit) consistency model for the team.","Test LWT statements in a staging keyspace before deploying."],"tags":["cassandra","consistency-level","lwt","write"],"backgroundTag":"invalid-argument-value","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"}