{"record":{"id":"b1b2a4909580b1e3","repo":"apache/cassandra","slug":"missing-mandatory-option-s","errorCode":null,"errorMessage":"Missing mandatory option '%s'","messagePattern":"Missing mandatory option '(.+?)'","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/CreateKeyspaceStatement.java","lineNumber":81,"sourceCode":"    {\n        if (expandedCql != null)\n            return expandedCql;\n        return super.cql();\n    }\n\n    @Override\n    public boolean compatibleWith(ClusterMetadata metadata)\n    {\n        return metadata.directory.commonSerializationVersion.isAtLeast(Version.V0);\n    }\n\n    @Override\n    public Keyspaces apply(ClusterMetadata metadata)\n    {\n        attrs.validate();\n\n        if (!attrs.hasOption(Option.REPLICATION))\n            throw ire(\"Missing mandatory option '%s'\", Option.REPLICATION);\n\n        if (attrs.getReplicationStrategyClass() != null && attrs.getReplicationStrategyClass().equals(SimpleStrategy.class.getSimpleName()))\n            Guardrails.simpleStrategyEnabled.ensureEnabled(\"SimpleStrategy\", state);\n\n        Keyspaces schema = metadata.schema.getKeyspaces();\n        if (schema.containsKeyspace(keyspaceName))\n        {\n            if (ifNotExists)\n                return schema;\n\n            throw new AlreadyExistsException(keyspaceName);\n        }\n\n        // we deduplicate ReplicationParams here to use the same objects in KeyspaceMetadata\n        // as we have as keys in metadata.placements to have a fast map lookup\n        // ReplicationParams are immutable, so it is a safe optimization\n        KeyspaceParams keyspaceParams = attrs.asNewKeyspaceParams();\n        ReplicationParams replicationParams = metadata.placements().deduplicateReplicationParams(keyspaceParams.replication);","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/CreateKeyspaceStatement.java#L63-L99","documentation":"CREATE KEYSPACE requires a replication option. If the WITH attributes omit REPLICATION (e.g. `WITH DURABLE_WRITES = true` only), the statement fails because Cassandra must know how to replicate the keyspace.","triggerScenarios":"`CREATE KEYSPACE ks WITH DURABLE_WRITES = true;` — attrs.hasOption(Option.REPLICATION) is false in apply().","commonSituations":"Hand-written DDL forgetting the replication map; tooling that emits only non-replication options; copy-paste of a snippet without its WITH clause.","solutions":["Add a REPLICATION map: CREATE KEYSPACE ks WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 3};","Use SimpleStrategy only for dev: WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}."],"exampleFix":"// before\nCREATE KEYSPACE ks WITH DURABLE_WRITES = true;\n\n// after\nCREATE KEYSPACE ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3};","handlingStrategy":"validation","validationCode":"if (!cql.matches(\"(?s).*replication\\\\s*=\\\\s*\\\\{.*\")) throw new IllegalArgumentException(\"CREATE KEYSPACE requires a replication option\");","typeGuard":null,"tryCatchPattern":"try { session.execute(ddl); } catch (InvalidQueryException e) { if (e.getMessage().contains(\"Missing mandatory option\")) { /* add WITH replication = {...} */ } else throw e; }","preventionTips":["Never hand-write CREATE KEYSPACE without the replication map","Use standard keyspace-creation snippets per environment","Validate DDL against a parser or lint in CI"],"tags":["cassandra","cql","keyspace","replication"],"backgroundTag":"missing-required-option","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"}