apache/cassandra · error · InvalidRequestException
Cannot specify options for a non-CUSTOM index
Error message
Cannot specify options for a non-CUSTOM index
What it means
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.
Source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/IndexAttributes.java:57
public String customClass;
static
{
keywords.add(KW_OPTIONS);
}
public void validate() throws RequestValidationException
{
validate(keywords, obsoleteKeywords);
if (isCustom && customClass == null)
throw new InvalidRequestException("CUSTOM index requires specifiying the index class");
if (!isCustom && customClass != null)
throw new InvalidRequestException("Cannot specify index class for a non-CUSTOM index");
if (!isCustom && !properties.isEmpty())
throw new InvalidRequestException("Cannot specify options for a non-CUSTOM index");
if (getRawOptions().containsKey(IndexTarget.CUSTOM_INDEX_OPTION_NAME))
throw new InvalidRequestException(String.format("Cannot specify %s as a CUSTOM option",
IndexTarget.CUSTOM_INDEX_OPTION_NAME));
if (getRawOptions().containsKey(IndexTarget.TARGET_OPTION_NAME))
throw new InvalidRequestException(String.format("Cannot specify %s as a CUSTOM option",
IndexTarget.TARGET_OPTION_NAME));
}
private Map<String, String> getRawOptions() throws SyntaxException
{
Map<String, String> options = getMap(KW_OPTIONS);
return options == null ? Collections.emptyMap() : options;
}
public Map<String, String> getOptions() throws SyntaxExceptionView on GitHub (pinned to 88fd0f6a0e)
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
Example fix
// before
CREATE INDEX ON users (email) WITH OPTIONS = {'case_sensitive': 'false'};
// after
CREATE CUSTOM INDEX ON users (email) USING 'org.example.CaseInsensitiveIndex' WITH OPTIONS = {'case_sensitive': 'false'}; Defensive patterns
Strategy: validation
Validate before calling
const isCustom = ddl.includes("USING '");
const hasOptions = /WITH\s+OPTIONS\s*=/i.test(ddl);
if (hasOptions && !isCustom) throw new Error('Index options require a CUSTOM index (add USING clause or drop OPTIONS)'); Prevention
- 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
When it happens
Trigger: 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'}`.
Common situations: 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.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- REVOKE operation is not supported by AllowAllAuthorizer
- Key may not be empty
- Key may not be empty
- Key length of %d is longer than maximum of %d
- Column value does not satisfy value constraint for column '<
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/edab344b0ab0c65a.
Report an issue: GitHub.