{"record":{"id":"40d8acb9dba4eab6","repo":"apache/cassandra","slug":"must-specify-index-implementation-via-using","errorCode":null,"errorMessage":"Must specify index implementation via USING","messagePattern":"Must specify index implementation via USING","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java","lineNumber":395,"sourceCode":"        {\n            String keyspaceName = tableName.hasKeyspace()\n                                ? tableName.getKeyspace()\n                                : indexName.hasKeyspace() ? indexName.getKeyspace() : state.getKeyspace();\n\n            if (tableName.hasKeyspace() && !keyspaceName.equals(tableName.getKeyspace()))\n                throw ire(KEYSPACE_DOES_NOT_MATCH_TABLE, keyspaceName, tableName);\n\n            if (indexName.hasKeyspace() && !keyspaceName.equals(indexName.getKeyspace()))\n                throw ire(KEYSPACE_DOES_NOT_MATCH_INDEX, keyspaceName, tableName);\n            \n            // Set the configured default 2i implementation if one isn't specified with USING:\n            if (attrs.customClass == null)\n            {\n                if (DatabaseDescriptor.getDefaultSecondaryIndexEnabled())\n                    attrs.customClass = DatabaseDescriptor.getDefaultSecondaryIndex();\n                else\n                    // However, operators may require an implementation be specified\n                    throw ire(MUST_SPECIFY_INDEX_IMPLEMENTATION);\n            }\n            \n            // If we explicitly specify the index type \"legacy_local_table\", we can just clear the custom class, and the\n            // non-custom 2i creation process will begin. Otherwise, if an index type has been specified with \n            // USING, make sure the appropriate custom index is created.\n            if (attrs.customClass != null)\n            {\n                if (!attrs.isCustom && attrs.customClass.equalsIgnoreCase(CassandraIndex.NAME))\n                    attrs.customClass = null;\n                else\n                    attrs.isCustom = true;\n            }\n\n            return new CreateIndexStatement(keyspaceName, tableName.getName(), indexName.getName(), rawIndexTargets, attrs, ifNotExists);\n        }\n    }\n}\n","sourceCodeStart":377,"sourceCodeEnd":413,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java#L377-L413","documentation":"When no default secondary index implementation is configured (default_secondary_index disabled), a CREATE INDEX without an explicit `USING <implementation>` cannot pick an implementation and is rejected. Cassandra requires the operator to state which 2i engine (e.g. legacy LocalTableSecondaryIndex or SAI) to use.","triggerScenarios":"`CREATE INDEX idx ON t (col);` while cassandra.yaml does not enable a default secondary index (DatabaseDescriptor.getDefaultSecondaryIndexEnabled() is false), so attrs.customClass stays null after prepare().","commonSituations":"Upgrading clusters where operators deliberately disabled the default 2i (e.g. after SAI adoption) and application DDL no longer specifies USING; fresh deployments with hardened config where the default was turned off.","solutions":["Add USING to the statement: CREATE CUSTOM INDEX ... ON t (col) USING 'StorageAttachedIndex'.","Re-enable a default index implementation in cassandra.yaml (default_secondary_index setting).","Set the desired custom index class explicitly in all migration scripts."],"exampleFix":"// before\nCREATE INDEX idx ON t (col);\n\n// after\nCREATE CUSTOM INDEX idx ON t (col) USING 'StorageAttachedIndex';","handlingStrategy":"validation","validationCode":"if (!cql.toLowerCase().contains(\"using\") && !defaultSecondaryIndexEnabled()) throw new IllegalArgumentException(\"Add USING '<index implementation>' to CREATE INDEX\");","typeGuard":null,"tryCatchPattern":"try { session.execute(cql); } catch (InvalidQueryException e) { if (e.getMessage().contains(\"Must specify index implementation\")) { /* append USING clause and retry */ } else throw e; }","preventionTips":["Always specify USING in CREATE INDEX statements for portability","Track the default_secondary_index setting per environment","Pin the index implementation explicitly in migration templates"],"tags":["cassandra","cql","index","configuration"],"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"}