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

  1. Remove all analyzer options from the CREATE INDEX statement for primary key columns.
  2. Create the SAI index without an analyzer class; key columns are matched exactly.
  3. 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

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


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