apache/cassandra · error · InvalidRequestException

Function name ' ' is invalid

Error message

Function name '%s' is invalid

What it means

Thrown when the function name supplied to CREATE FUNCTION (or CREATE AGGREGATE) fails FunctionName.isNameValid — i.e. it is not a valid Cassandra identifier/keyspace-qualified name under the current naming rules.

Solutions

  1. Rename the function to a valid identifier ([a-zA-Z][a-zA-Z0-9_]* pattern, not a reserved keyword).
  2. Wrap a keyword-like or unusual name in double quotes: CREATE FUNCTION ks."my-func"(...).
  3. Validate identifiers in code that generates DDL before executing it.
  4. Fully qualify with a valid keyspace prefix if the intended name included one.

Example fix

// before
CREATE FUNCTION ks.1st_fn(i int) RETURNS NULL ON NULL INPUT RETURNS int ...;
// after
CREATE FUNCTION ks.first_fn(i int) RETURNS NULL ON NULL INPUT RETURNS int ...;
Defensive patterns

Strategy: validation

Validate before calling

// Java
public static boolean isValidFnName(String name) {
    String[] parts = name.split("\\.");
    if (parts.length > 2) return false;
    for (String p : parts)
        if (!p.matches("[a-zA-Z][a-zA-Z0-9_]*")) return false; // or a quoted identifier
    return true;
}

Type guard

boolean isQuotedOrPlainIdentifier(String s) {
    return (s.startsWith("\"") && s.endsWith("\"")) || s.matches("[a-zA-Z][a-zA-Z0-9_]*");
}

Try / catch

try { session.execute(ddl); }
catch (InvalidRequestException e) {
    if (e.getMessage().contains("is invalid")) { /* quote the identifier or rename */ }
    else throw e;
}

Prevention

When it happens

Trigger: CREATE FUNCTION with a name containing illegal characters, starting with a digit, using reserved keywords unquoted, or an empty name.

Common situations: Programmatic DDL generation interpolating unvalidated identifiers; names copied from systems with laxer identifier rules; missing quotes around a name that needs quoting.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateFunctionStatement.java:103

        this.ifNotExists = ifNotExists;
    }

    @Override
    public boolean compatibleWith(ClusterMetadata metadata)
    {
        return metadata.directory.commonSerializationVersion.isAtLeast(Version.V0);
    }

    // TODO: replace affected aggregates !!
    public Keyspaces apply(ClusterMetadata metadata)
    {
        if (ifNotExists && orReplace)
            throw ire("Cannot use both 'OR REPLACE' and 'IF NOT EXISTS' directives");

        UDFunction.assertUdfsEnabled(language);

        if (!FunctionName.isNameValid(functionName))
            throw ire("Function name '%s' is invalid", functionName);

        if (new HashSet<>(argumentNames).size() != argumentNames.size())
            throw ire("Duplicate argument names for given function %s with argument names %s", functionName, argumentNames);

        rawArgumentTypes.stream()
                        .filter(raw -> !raw.isImplicitlyFrozen() && raw.isFrozen())
                        .findFirst()
                        .ifPresent(t -> { throw ire("Argument '%s' cannot be frozen; remove frozen<> modifier from '%s'", t, t); });

        if (!rawReturnType.isImplicitlyFrozen() && rawReturnType.isFrozen())
            throw ire("Return type '%s' cannot be frozen; remove frozen<> modifier from '%s'", rawReturnType, rawReturnType);

        Keyspaces schema = metadata.schema.getKeyspaces();
        KeyspaceMetadata keyspace = schema.getNullable(keyspaceName);
        if (null == keyspace)
            throw ire("Keyspace '%s' doesn't exist", keyspaceName);

        List<AbstractType<?>> argumentTypes =

View on GitHub (pinned to 88fd0f6a0e)