{"record":{"id":"edab344b0ab0c65a","repo":"apache/cassandra","slug":"cannot-specify-options-for-a-non-custom-index","errorCode":null,"errorMessage":"Cannot specify options for a non-CUSTOM index","messagePattern":"Cannot specify options for a non-CUSTOM index","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/IndexAttributes.java","lineNumber":57,"sourceCode":"    public String customClass;\n\n    static\n    {\n        keywords.add(KW_OPTIONS);\n    }\n\n    public void validate() throws RequestValidationException\n    {\n        validate(keywords, obsoleteKeywords);\n\n        if (isCustom && customClass == null)\n            throw new InvalidRequestException(\"CUSTOM index requires specifiying the index class\");\n\n        if (!isCustom && customClass != null)\n            throw new InvalidRequestException(\"Cannot specify index class for a non-CUSTOM index\");\n\n        if (!isCustom && !properties.isEmpty())\n            throw new InvalidRequestException(\"Cannot specify options for a non-CUSTOM index\");\n\n        if (getRawOptions().containsKey(IndexTarget.CUSTOM_INDEX_OPTION_NAME))\n            throw new InvalidRequestException(String.format(\"Cannot specify %s as a CUSTOM option\",\n                                                            IndexTarget.CUSTOM_INDEX_OPTION_NAME));\n\n        if (getRawOptions().containsKey(IndexTarget.TARGET_OPTION_NAME))\n            throw new InvalidRequestException(String.format(\"Cannot specify %s as a CUSTOM option\",\n                                                            IndexTarget.TARGET_OPTION_NAME));\n\n    }\n\n    private Map<String, String> getRawOptions() throws SyntaxException\n    {\n        Map<String, String> options = getMap(KW_OPTIONS);\n        return options == null ? Collections.emptyMap() : options;\n    }\n\n    public Map<String, String> getOptions() throws SyntaxException","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/IndexAttributes.java#L39-L75","documentation":"IndexAttributes.validate() enforces that index OPTIONS (custom properties) may only be supplied when the index is declared USING a custom index class. When CREATE/ALTER INDEX has no custom class but includes options like `WITH OPTIONS = {...}`, Cassandra rejects the statement with InvalidRequestException because those options only make sense for a third-party (CUSTOM) index implementation.","triggerScenarios":"Executing CREATE INDEX or ALTER TABLE ... ADD INDEX with a non-CUSTOM (built-in) index while passing index options/properties, e.g. `CREATE INDEX ON t (c) WITH OPTIONS = {'x': 'y'}`.","commonSituations":"Copy-pasted DDL written for a storage-attached index (SAI, SASI) applied to a default secondary index; schema scripts ported between index implementations; forgetting the `USING 'class'` clause while keeping its OPTIONS.","solutions":["Add `USING 'com.example.CustomIndex'` to make it a CUSTOM index, or","Remove the OPTIONS/properties clause since a built-in index takes no custom options"],"exampleFix":"// before\nCREATE INDEX ON users (email) WITH OPTIONS = {'case_sensitive': 'false'};\n// after\nCREATE CUSTOM INDEX ON users (email) USING 'org.example.CaseInsensitiveIndex' WITH OPTIONS = {'case_sensitive': 'false'};","handlingStrategy":"validation","validationCode":"const isCustom = ddl.includes(\"USING '\");\nconst hasOptions = /WITH\\s+OPTIONS\\s*=/i.test(ddl);\nif (hasOptions && !isCustom) throw new Error('Index options require a CUSTOM index (add USING clause or drop OPTIONS)');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only pass WITH OPTIONS together with a USING '<class>' clause","Validate generated DDL with a parser or EXPLAIN-style dry run before execution","Never copy OPTIONS clauses between built-in and custom index DDL"],"tags":["cql","index","validation"],"backgroundTag":"schema-validation-failed","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"}