apache/cassandra · error · InvalidRequestException
Cannot specify as a CUSTOM option
Error message
Cannot specify %s as a CUSTOM option
What it means
When creating/altering a CUSTOM index, Cassandra reserves the internal option key `class_name` (IndexTarget.CUSTOM_INDEX_OPTION_NAME) for itself; it is set via the `USING` clause, not via OPTIONS. Supplying `class_name` inside the OPTIONS map is ambiguous and rejected with InvalidRequestException during IndexAttributes.validate().
Solutions
- Remove the 'class_name' key from the OPTIONS map
- Keep the index class only in the USING '<class>' clause
Example fix
// before
CREATE CUSTOM INDEX ON t (c) USING 'com.x.Idx' WITH OPTIONS = {'class_name': 'com.x.Idx'};
// after
CREATE CUSTOM INDEX ON t (c) USING 'com.x.Idx' WITH OPTIONS = {'mode': 'CONTAINS'}; Defensive patterns
Strategy: validation
Validate before calling
const opts = parseOptions(ddl);
if (opts.class_name !== undefined) throw new Error("Remove reserved key 'class_name' from OPTIONS; use USING clause"); Prevention
- Treat 'class_name' and 'target' as reserved keys in index OPTIONS
- Always specify custom index class via USING '<class>'
- Sanitize user-provided option maps before emitting CQL
When it happens
Trigger: CREATE CUSTOM INDEX ... USING '...' WITH OPTIONS = {'class_name': '...'} — the reserved key appears in the raw options map.
Common situations: Migrating from Cassandra 2.x-era SASI/third-party DDL where class_name was spelled inside options; LLM/ORM-generated CQL duplicating the USING class into OPTIONS.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot create index on non-frozen UDT column
- Cannot specify options for a non-CUSTOM index
- Cannot use CREATE TABLE LIKE on an index table
- Index ' . ' doesn't exist
- Keyspace ' ' doesn't exist
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/c9e1564e6f05f04b.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/IndexAttributes.java:60
{
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 SyntaxException
{
Map<String, String> options = new HashMap<>(getRawOptions());
options.put(IndexTarget.CUSTOM_INDEX_OPTION_NAME, customClass);View on GitHub (pinned to 88fd0f6a0e)