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 SyntaxException

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Add `USING 'com.example.CustomIndex'` to make it a CUSTOM index, or
  2. 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

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/edab344b0ab0c65a. Report an issue: GitHub.