apache/cassandra · error · InvalidRequestException

Invalid null value for

Error message

Invalid null value for %s in %s

What it means

In a multicolumn restriction, one of the per-column element values bound for the restriction is null. validateElements iterates each column of the tuple/multi-column expression and throws, naming both the offending column and the columns expression.

Solutions

  1. Ensure every component of the multi-column tuple is bound to a non-null value
  2. Restrict only the columns whose values are known and drop the tuple predicate otherwise
  3. Validate tuple elements client-side before binding

Example fix

// before
session.execute(ps.bind(1, null)); // (a, b) = (?, ?)
// after
session.execute(ps.bind(1, "x"));
Defensive patterns

Strategy: validation

Validate before calling

Object[] tuple = ...; for (Object o : tuple) if (o == null) throw new IllegalArgumentException("tuple element null");

Type guard

boolean tupleComplete(Object[] t) { return java.util.Arrays.stream(t).allMatch(java.util.Objects::nonNull); }

Try / catch

catch (InvalidRequestException e) { if (e.getMessage().contains("Invalid null value")) logMissingTupleComponents(); }

Prevention

When it happens

Trigger: Executing 'WHERE (a, b) = (?, ?)' with one of the tuple's bound values null.

Common situations: Partial tuple bindings from application code where some tuple components are missing; mapping a nullable struct to a CQL tuple restriction.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/restrictions/SimpleRestriction.java:365

    private void validate(ByteBuffer buffer)
    {
        if (buffer == null)
            throw invalidRequest("Invalid null value for %s", columnsExpression);
        if (buffer == ByteBufferUtil.UNSET_BYTE_BUFFER)
            throw invalidRequest("Invalid unset value for %s", columnsExpression);
    }

    private void validateElements(List<ByteBuffer> elements)
    {
        validate(elements);

        List<ColumnMetadata> columns = columns();
        for (int i = 0, m = columns.size(); i < m; i++)
        {
            ColumnMetadata column = columns.get(i);
            ByteBuffer element = elements.get(i);
            if (element == null)
                throw invalidRequest("Invalid null value for %s in %s",
                                     column.name.toCQLString(), columnsExpression);
            if (element == ByteBufferUtil.UNSET_BYTE_BUFFER)
                throw invalidRequest("Invalid unset value for %s in %s",
                                     column.name.toCQLString(), columnsExpression);
        }
    }

    @Override
    public void addToRowFilter(RowFilter filter, IndexRegistry indexRegistry, FunctionContext context, IndexHints indexHints)
    {
        if (isOnToken())
            throw new UnsupportedOperationException();

        ColumnMetadata column = firstColumn();
        switch (columnsExpression.kind())
        {
            case SINGLE_COLUMN:
                List<ByteBuffer> buffers = bindAndGet(context);

View on GitHub (pinned to 88fd0f6a0e)