apache/cassandra · error · InvalidRequestException

Trigger ' ' on ' . ' doesn't exist

Error message

Trigger '%s' on '%s.%s' doesn't exist

What it means

Existence guard in DropTriggerStatement.apply(): the named trigger is not defined on the target table (or the keyspace/table itself is missing), so table.triggers has no entry for triggerName. Without IF EXISTS, the drop is rejected with InvalidRequestException naming the trigger and the table.

Solutions

  1. Add IF EXISTS to make the drop idempotent; verify the trigger name and table with DESCRIBE TABLE; check that the trigger was not already dropped on another node before retrying.

Example fix

// before
DROP TRIGGER tg ON ks.tbl;
// after
DROP TRIGGER IF EXISTS tg ON ks.tbl;
Defensive patterns

Strategy: validation

Validate before calling

var exists = session.execute("SELECT trigger_name FROM system_schema.triggers WHERE keyspace_name=? AND table_name=? AND trigger_name=?", ks, table, trigger).iterator().hasNext();
if (exists) session.execute("DROP TRIGGER " + trigger + " ON " + ks + "." + table);

Try / catch

try { session.execute(ddl); } catch (InvalidRequest e) { if (e.getMessage().contains("doesn't exist")) log.info("Trigger already absent"); else throw e; }

Prevention

When it happens

Trigger: Executing DROP TRIGGER <name> ON <ks>.<table> when no trigger with that name exists in the table's trigger metadata; misspelling the trigger name; running against a cluster where the trigger was already dropped.

Common situations: Typos in trigger names; re-running DDL scripts that already executed; environments (e.g. staging) where the trigger was never created.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/DropTriggerStatement.java:75

    public Keyspaces apply(ClusterMetadata metadata)
    {
        Keyspaces schema = metadata.schema.getKeyspaces();
        KeyspaceMetadata keyspace = schema.getNullable(keyspaceName);

        TableMetadata table = null == keyspace
                            ? null
                            : keyspace.tables.getNullable(tableName);

        TriggerMetadata trigger = null == table
                                ? null
                                : table.triggers.get(triggerName).orElse(null);

        if (null == trigger)
        {
            if (ifExists)
                return schema;

            throw ire("Trigger '%s' on '%s.%s' doesn't exist", triggerName, keyspaceName, tableName);
        }

        TableMetadata newTable = table.withSwapped(table.triggers.without(triggerName));
        return schema.withAddedOrUpdated(keyspace.withSwapped(keyspace.tables.withSwapped(newTable)));
    }

    SchemaChange schemaChangeEvent(KeyspacesDiff diff)
    {
        return new SchemaChange(Change.UPDATED, Target.TABLE, keyspaceName, tableName);
    }

    public void authorize(ClientState client)
    {
        client.ensureIsSuperuser("Only superusers are allowed to perfrom DROP TRIGGER queries");
    }

    @Override
    public AuditLogContext getAuditLogContext()

View on GitHub (pinned to 88fd0f6a0e)