apache/cassandra · error · InvalidRequestException

Invalid unset map key

Error message

Invalid unset map key

What it means

Thrown at execution when the key bound for a single-key map write is the UNSET sentinel rather than a real value. UNSET means 'do not modify' and is not valid for identifying a map entry, so the request fails.

Solutions

  1. Bind a concrete key value; use null (which also errors) only deliberately — for 'skip' semantics restructure the statement.
  2. Build the statement conditionally so unset keys produce no map-key clause.
  3. Use a whole-map assignment `SET m = ?` when the full map is known.

Example fix

// before
boundStatement.setBytesToUnset(i); // key
// after
boundStatement.setString(i, actualKey); // must be a real key value
Defensive patterns

Strategy: validation

Validate before calling

if (isUnset(mapKey)) throw new IllegalArgumentException("map key must be a concrete value, not UNSET");

Type guard

boolean isConcrete(ByteBuffer b) { return b != null && b != ByteBufferUtil.UNSET_BYTE_BUFFER; }

Try / catch

try { session.execute(stmt); } catch (InvalidRequestException e) { if (e.getMessage().contains("Invalid unset map key")) { /* provide a real key or restructure */ } else throw e; }

Prevention

When it happens

Trigger: Executing `UPDATE t SET m[?] = ? WHERE ...` where the driver bound the key as unset (UNSET_VALUE / unset bind parameter).

Common situations: Batch builders that mark parameters unset for conditional writes; drivers' unset-value support applied to map keys; templated code that omits keys but keeps the statement.

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/5be1d9059b0a43c9. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/terms/Maps.java:293

            this.k = k;
        }

        @Override
        public void collectMarkerSpecification(VariableSpecifications boundNames, Object owner)
        {
            super.collectMarkerSpecification(boundNames, owner);
            k.collectMarkerSpecification(boundNames, owner);
        }

        public void execute(DecoratedKey partitionKey, RowUpdateBuilder builder) throws InvalidRequestException
        {
            assert column.type.isMultiCell() : "Attempted to set a value for a single key on a frozen map";
            ByteBuffer key = k.bindAndGet(builder);
            ByteBuffer value = t.bindAndGet(builder);
            if (key == null)
                throw new InvalidRequestException("Invalid null map key");
            if (key == ByteBufferUtil.UNSET_BYTE_BUFFER)
                throw new InvalidRequestException("Invalid unset map key");

            CellPath path = CellPath.create(key);

            if (value == null)
            {
                builder.addTombstone(column, path);
            }
            else if (value != ByteBufferUtil.UNSET_BYTE_BUFFER)
            {
                builder.addCell(column, path, value);
            }
        }
    }

    public static class Putter extends Operation
    {
        public Putter(ColumnMetadata column, Term t)
        {

View on GitHub (pinned to 88fd0f6a0e)