apache/cassandra · error · InvalidRequestException

Invalid null value for

Error message

Invalid null value for %s

What it means

A restriction term bound to null is rejected: SimpleRestriction.validate(List) throws when the bound list value for the restricted columns expression is null. Cassandra requires concrete bound values for restriction terms; null cannot be used as a comparison operand.

Solutions

  1. Set the bound variable with the driver (e.g. boundStatement.setString(i, value)) before executing
  2. Validate all bound parameters are non-null client-side before execute
  3. Remove the restriction clause instead of passing null when filtering is not intended

Example fix

// before
PreparedStatement ps = session.prepare("SELECT * FROM t WHERE k IN ?");
session.execute(ps.bind());
// after
PreparedStatement ps = session.prepare("SELECT * FROM t WHERE k IN ?");
session.execute(ps.bind(Arrays.asList(1, 2)));
Defensive patterns

Strategy: validation

Validate before calling

// before executing a bound statement
for (int i = 0; i < values.length; i++) if (values[i] == null) throw new IllegalArgumentException("bind value " + i + " is null");

Type guard

boolean isBound(Object v) { return v != null; }

Try / catch

catch (InvalidRequestException e) { if (e.getMessage().startsWith("Invalid null value")) logMissingBindings(); }

Prevention

When it happens

Trigger: Executing a prepared statement without setting a bound value for the restriction column (bound term resolves to null).

Common situations: Forgetting to bind a variable before executing a prepared statement; driver defaults unset positional parameters to null in a List-typed restriction.

Related errors


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

Appendix: source

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

    private ByteBuffer bindAndGetSingle(FunctionContext context)
    {
        ByteBuffer buffer = values.bindAndGetSingleTermValue(context);
        validate(buffer);
        return buffer;
    }

    private List<List<ByteBuffer>> bindAndGetElements(FunctionContext context)
    {
        List<List<ByteBuffer>> elementsList = values.bindAndGetElements(context);
        validate(elementsList);
        elementsList.forEach(this::validateElements);
        return elementsList;
    }

    private void validate(List<?> list)
    {
        if (list == null)
            throw invalidRequest("Invalid null value for %s", columnsExpression);
        if (list == Term.UNSET_LIST)
            throw invalidRequest("Invalid unset value for %s", columnsExpression);
    }

    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++)

View on GitHub (pinned to 88fd0f6a0e)