apache/cassandra · error · ConfigurationException

Illegal index name

Error message

Illegal index name ${name}

What it means

Generic guard in IndexMetadata.validate: the index name violates the required identifier pattern (alphanumeric/underscore, must not be empty) — message 'Illegal index name ${name}'. Thrown as InvalidRequestException during CREATE/DROP INDEX schema validation; the at-fault input is the user-supplied index name string.

Solutions

  1. Rename the index using only alphanumeric characters and underscores
  2. Quote the identifier in CQL if needed, but keep the characters valid
  3. Sanitize generated names: replace invalid chars with '_' before creating IndexMetadata

Example fix

// before
IndexMetadata.raw("idx(col desc)", ...)
// after
IndexMetadata.raw("idx_col_desc", ...)
Defensive patterns

Strategy: validation

Validate before calling

if (!name.matches("[a-zA-Z0-9_]+")) throw new IllegalArgumentException("illegal index name: " + name);

Try / catch

try { index.validate(table); } catch (ConfigurationException e) { log.error("invalid index name " + index.name, e); }

Prevention

When it happens

Trigger: Creating an index whose name contains characters rejected by isValidCharsName (e.g. spaces, dots, non-ASCII symbols), then validate() is called during schema construction/creation.

Common situations: Programmatic schema generation deriving index names from column expressions like 'idx(col desc)' which contain parentheses or spaces; copying a display name straight into the index name.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/schema/IndexMetadata.java:137

                                                              .collect(Collectors.joining(", ")));
        return new IndexMetadata(name, newOptions, kind);
    }

    public static String generateDefaultIndexName(String table, ColumnIdentifier column)
    {
        return PATTERN_NON_WORD_CHAR.matcher(table + '_' + column.toString() + "_idx").replaceAll("");
    }

    public static String generateDefaultIndexName(String table)
    {
        return PATTERN_NON_WORD_CHAR.matcher(table + "_idx").replaceAll("");
    }

    public void validate(TableMetadata table)
    {
        // TODO: address validating the length by CASSANDRA-20445
        if (!isValidCharsName(name))
            throw new ConfigurationException("Illegal index name " + name);

        if (kind == null)
            throw new ConfigurationException("Index kind is null for index " + name);

        if (kind == Kind.CUSTOM)
        {
            if (options == null || !options.containsKey(IndexTarget.CUSTOM_INDEX_OPTION_NAME))
                throw new ConfigurationException(String.format("Required option missing for index %s : %s",
                                                               name, IndexTarget.CUSTOM_INDEX_OPTION_NAME));

            // Get the fully qualified class name:
            String className = getIndexClassName();

            Class<? extends Index> indexerClass = FBUtilities.classForNameWithoutInitialization(className, "custom indexer", Index.class);
            validateCustomIndexOptions(table, indexerClass, options);
        }
    }

View on GitHub (pinned to 88fd0f6a0e)