apache/cassandra · error · InvalidRequestException

Invalid unset value for

Error message

Invalid unset value for %s in %s

What it means

In a multicolumn restriction, one of the per-column element values is the UNSET sentinel. validateElements checks each ByteBuffer element against ByteBufferUtil.UNSET_BYTE_BUFFER and throws, identifying the column and columns expression.

Solutions

  1. Bind concrete values for all tuple components
  2. Rebuild the query with only the fully-bound tuple restriction
  3. Replace UNSET components with actual values or drop the whole predicate

Example fix

// before
session.execute(ps.bind(1, unsetValue));
// after
session.execute(ps.bind(1, 2));
Defensive patterns

Strategy: validation

Validate before calling

for (ByteBuffer b : elements) if (b == null || b == UNSET_SENTINEL) throw new IllegalArgumentException("unset tuple element");

Type guard

boolean tupleFullySet(java.nio.ByteBuffer[] t) { return java.util.Arrays.stream(t).allMatch(b -> b != null && b != UNSET_SENTINEL); }

Try / catch

catch (InvalidRequestException e) { if (e.getMessage().contains("Invalid unset value")) rebuildQuery(); }

Prevention

When it happens

Trigger: Executing a multi-column restriction like 'WHERE (a, b) > (?, ?)' where one tuple element was set to UNSET.

Common situations: Using unset-skip semantics on individual tuple components, which multicolumn restrictions do not support.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

            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);
                if (operator.kind() != Operator.Kind.BINARY)
                {
                    if (operator == Operator.IN && !column.type.isCounter())

View on GitHub (pinned to 88fd0f6a0e)