apache/cassandra · error · InvalidRequestException

Currently only Java UDFs are available in Cassandra. For…

Error message

Currently only Java UDFs are available in Cassandra. For more information - CASSANDRA-18252 and CASSANDRA-17281

What it means

After confirming UDFs are enabled, assertUdfsEnabled verifies the UDF language is 'java'; since CASSANDRA-18252/CASSANDRA-17281 non-Java (e.g. JavaScript) UDFs were removed and any attempt to create or execute them is rejected with InvalidRequestException.

Solutions

  1. Rewrite the UDF in Java and use LANGUAGE java in CREATE FUNCTION
  2. Drop and recreate legacy non-Java functions as Java UDFs
  3. Remove stale references to JavaScript UDFs from schema/migration scripts

Example fix

// before
CREATE FUNCTION f(x int) RETURNS NULL ON NULL INPUT RETURNS int LANGUAGE javascript AS 'return x+1;';
// after
CREATE FUNCTION f(x int) RETURNS NULL ON NULL INPUT RETURNS int LANGUAGE java AS 'return x + 1;';
Defensive patterns

Strategy: validation

Validate before calling

if (!"java".equalsIgnoreCase(languageClause)) throw new IllegalArgumentException("Only LANGUAGE java is supported (CASSANDRA-18252/17281)");

Try / catch

try { session.execute(createFunctionCql); } catch (InvalidRequestException e) { if (e.getMessage().contains("only Java UDFs")) { /* rewrite function in Java */ } throw e; }

Prevention

When it happens

Trigger: CREATE FUNCTION ... LANGUAGE javascript (or any non-Java language), or executing a UDF persisted with a non-Java language (e.g. upgraded from an older Cassandra that allowed JavaScript UDFs).

Common situations: Upgrading a cluster from pre-4.1/5.0 versions where JavaScript UDFs existed; copying old CQL scripts that use LANGUAGE javascript; tooling that still emits non-Java language clauses.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/functions/UDFunction.java:442

        catch (InvalidRequestException e)
        {
            throw e;
        }
        catch (Throwable t)
        {
            logger.debug("Invocation of user-defined function '{}' failed", this, t);
            if (t instanceof VirtualMachineError)
                throw (VirtualMachineError) t;
            throw FunctionExecutionException.create(this, t);
        }
    }

    public static void assertUdfsEnabled(String language)
    {
        if (!DatabaseDescriptor.enableUserDefinedFunctions())
            throw new InvalidRequestException("User-defined functions are disabled in cassandra.yaml - set user_defined_functions_enabled=true to enable");
        if (!"java".equalsIgnoreCase(language))
            throw new InvalidRequestException("Currently only Java UDFs are available in Cassandra. For more information - CASSANDRA-18252 and CASSANDRA-17281");
    }

    static void initializeThread()
    {
        // Get the TypeCodec stuff in Java Driver initialized.
        // This is to get the classes loaded outside of the restricted sandbox's security context of a UDF.
        TypeCodec.inet().format(InetAddress.getLoopbackAddress());
        TypeCodec.ascii().format("");
    }

    private static final class ThreadIdAndCpuTime extends CompletableFuture<Object>
    {
        long threadId;
        long cpuTime;

        ThreadIdAndCpuTime()
        {
            // Looks weird?

View on GitHub (pinned to 88fd0f6a0e)