apache/cassandra · error · InvalidRequestException
Analysis options are not supported on primary key columns, b
Error message
Analysis options are not supported on primary key columns, but found
What it means
SAI does not allow analyzer (text-processing) options on primary key columns. validateOptions extracts analyzer options from the CREATE INDEX options and, if the index target is a partition/clustering column and any analysis options are present, throws this InvalidRequestException (ANALYSIS_ON_KEY_COLUMNS_MESSAGE plus the offending options).
Source
Thrown at src/java/org/apache/cassandra/index/sai/StorageAttachedIndex.java:280
throw new InvalidRequestException("Failed to retrieve target column for: " + targetColumn);
}
// In order to support different index targets on non-frozen map, ie. KEYS, VALUE, ENTRIES, we need to put index
// name as part of index file name instead of column name. We only need to check that the target is different
// between indexes. This will only allow indexes in the same column with a different IndexTarget.Type.
//
// Note that: "metadata.indexes" already includes current index
if (metadata.indexes.stream().filter(index -> index.getIndexClassName().equals(StorageAttachedIndex.class.getName()))
.map(index -> TargetParser.parse(metadata, index.options.get(IndexTarget.TARGET_OPTION_NAME)))
.filter(Objects::nonNull).filter(t -> t.equals(target)).count() > 1)
{
throw new InvalidRequestException("Cannot create more than one storage-attached index on the same column: " + target.left);
}
Map<String, String> analysisOptions = AbstractAnalyzer.getAnalyzerOptions(options);
if (target.left.isPrimaryKeyColumn() && !analysisOptions.isEmpty())
{
throw new InvalidRequestException(ANALYSIS_ON_KEY_COLUMNS_MESSAGE + new CqlBuilder().append(analysisOptions));
}
IndexTermType indexTermType = IndexTermType.create(target.left, metadata.partitionKeyColumns(), target.right);
AbstractAnalyzer.fromOptions(indexTermType, analysisOptions);
IndexWriterConfig config = IndexWriterConfig.fromOptions(null, indexTermType, options);
// If we are indexing map entries we need to validate the subtypes
if (indexTermType.isComposite())
{
for (IndexTermType subType : indexTermType.subTypes())
{
if (!SUPPORTED_TYPES.contains(subType.asCQL3Type()) && !subType.isFrozen())
throw new InvalidRequestException("Unsupported type: " + subType.asCQL3Type());
}
}
else if (!SUPPORTED_TYPES.contains(indexTermType.asCQL3Type()) && !indexTermType.isFrozen())
{
throw new InvalidRequestException("Unsupported type: " + indexTermType.asCQL3Type());View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Remove all analyzer options from the CREATE INDEX statement for primary key columns.
- Create the SAI index without an analyzer class; key columns are matched exactly.
- If case-insensitive matching on a key column is needed, model the data differently (e.g., a denormalized lowercase column) instead of using analyzer options.
Example fix
// before
CREATE CUSTOM INDEX ON ks.tbl (partition_col) USING 'StorageAttachedIndex'
WITH OPTIONS = {'case_sensitive': 'false'};
// after
CREATE CUSTOM INDEX ON ks.tbl (partition_col) USING 'StorageAttachedIndex'; Defensive patterns
Strategy: validation
Validate before calling
const isPrimaryKey = schema.partitionKeys.concat(schema.clusteringKeys).some(k => k.name === targetColumn); if (isPrimaryKey && Object.keys(indexOptions).length > 0) throw new Error('no analyzer options allowed on key columns'); Try / catch
catch (InvalidRequestException e) { if (e.getMessage().contains("Analysis options are not supported on primary key columns")) { // strip options and retry without them } } Prevention
- Never copy analyzer options onto indexes of key columns
- Gate option emission in DDL generators on the column's role
- Keep key-column indexes option-free
When it happens
Trigger: CREATE CUSTOM INDEX with options like 'case_sensitive': 'false' or 'normalize_upper': 'true' (any NonTokenizingOptions keys) on a PRIMARY KEY column (partition key or clustering column).
Common situations: Adding case_sensitive/normalize options to an index on a clustering column copied from a text-column index definition; templated DDL generators applying analyzer options to all indexed columns.
Related errors
- CQL type
- QueryCancelledException(readCommand)
- Storage-attached index does not support the following IParti
- Missing target column
- A storage-attached index cannot be created over multiple col
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/77c2155d3e8902b0.
Report an issue: GitHub.