apache/cassandra · error · InvalidRequestException

Index is a duplicate of existing index

Error message

Index %s is a duplicate of existing index %s

What it means

CreateIndexStatement.apply: the requested index is identical (same targets/kind) to an existing index in the keyspace except for its name; Cassandra disallows such duplicate indexes to prevent redundant indexing.

Solutions

  1. Reuse the existing index instead of creating a new one.
  2. DROP the existing index first if a different definition is truly needed.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java:221 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java:221

        IndexMetadata.Kind kind = attrs.isCustom ? IndexMetadata.Kind.CUSTOM : IndexMetadata.Kind.COMPOSITES;

        indexTargets.forEach(t -> validateIndexTarget(table, kind, t, attrs));

        String name = null == indexName ? generateIndexName(keyspace, indexTargets) : indexName;

        Map<String, String> options = attrs.isCustom ? attrs.getOptions() : Collections.emptyMap();

        IndexMetadata index = IndexMetadata.fromIndexTargets(indexTargets, name, kind, options);

        // check to disallow creation of an index which duplicates an existing one in all but name
        IndexMetadata equalIndex = tryFind(table.indexes, i -> i.equalsWithoutName(index)).orNull();
        if (null != equalIndex)
        {
            if (ifNotExists)
                return schema;

            throw ire(INDEX_DUPLICATE_OF_EXISTING, index.name, equalIndex.name);
        }

        expandedCql = index.toCqlString(table, ifNotExists);
        verifyExpandedCql(expandedCql);

        TableMetadata newTable = table.withSwapped(table.indexes.with(index));
        newTable.validate();

        return schema.withAddedOrUpdated(keyspace.withSwapped(keyspace.tables.withSwapped(newTable)));
    }

    @Override
    Set<String> clientWarnings(KeyspacesDiff diff)
    {
        if (attrs.isCustom && attrs.customClass.equals(SASIIndex.class.getName()))
            return ImmutableSet.of(SASIIndex.USAGE_WARNING);

        return ImmutableSet.of();

View on GitHub (pinned to 88fd0f6a0e)