apache/cassandra · error · InvalidRequestException
Cannot specify index class for a non-CUSTOM index
Error message
Cannot specify index class for a non-CUSTOM index
What it means
The index class option (`USING '<class>'` / `customClass`) is only meaningful for CUSTOM indexes. Supplying a class with a non-custom `CREATE INDEX` is contradictory, so validate() rejects it with InvalidRequestException.
Source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/IndexAttributes.java:54
private static final Set<String> obsoleteKeywords = new HashSet<>();
public boolean isCustom;
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;View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Add the CUSTOM keyword: `CREATE CUSTOM INDEX i ON t (col) USING '<class>';` if a custom index was intended.
- Remove the `USING '<class>'` clause if a plain built-in secondary index was intended.
- Remember custom indexes also require the class name plus, optionally, OPTIONS.
Example fix
-- before CREATE INDEX i ON t (col) USING 'StorageAttachedIndex'; -- after CREATE CUSTOM INDEX i ON t (col) USING 'StorageAttachedIndex';
Defensive patterns
Strategy: validation
Validate before calling
boolean hasCustom = ddl.matches("(?i)CREATE\\s+CUSTOM\\s+INDEX");
boolean hasUsing = ddl.matches("(?i)USING\\s+'[^']+'");
if (!hasCustom && hasUsing) throw new IllegalArgumentException("USING requires the CUSTOM keyword"); Try / catch
try { session.execute(ddl); }
catch (InvalidQueryException e) {
if (e.getMessage().contains("non-CUSTOM index"))
throw new IllegalArgumentException("either drop USING or add the CUSTOM keyword", e);
throw e;
} Prevention
- Remember the canonical form: CREATE CUSTOM INDEX ... USING '<class>'
- Lint DDL for USING appearing without CUSTOM
- Copy DDL from docs/templates verbatim instead of reconstructing syntax
When it happens
Trigger: `CREATE INDEX i ON t (col) USING 'SomeIndexClass';` — a USING clause without the CUSTOM keyword.
Common situations: Users thinking `USING` alone creates a custom index (forgot the CUSTOM keyword); copy-pasted DDL where CUSTOM was dropped; confusion between built-in 2i and custom index syntax.
Related errors
- CUSTOM index requires specifiying the index class
- category %s not found in %s
- GRANT operation is not supported by AllowAllAuthorizer
- REVOKE operation is not supported by AllowAllAuthorizer
- LIST PERMISSIONS operation is not supported by AllowAllAutho
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/d750a16a57029bb7.
Report an issue: GitHub.