apache/cassandra · error · InvalidRequestException
Invalid unset map key for column
Error message
Invalid unset map key for column %s
What it means
Thrown by SimpleRestriction.addToRowFilter when the map key of a map-column restriction is the UNSET sentinel byte buffer. Cassandra treats UNSET as 'do not apply this binding', which is meaningless for a map key inside a row filter, so it is rejected.
Solutions
- Bind a concrete non-null key value to the map key parameter instead of unset.
- Rebuild the statement without the map-key restriction when the key is unknown, rather than leaving it unset.
- Treat unset as a client-side error: validate all bound key positions are set before executing.
- Avoid unset semantics for map keys; only the restriction's value parameter can safely be omitted logic-wise.
Example fix
// before
boundStatement.setToUnset(i); // key left unset
// after
if (key == null) throw new IllegalArgumentException("map key required");
boundStatement.setByteBuffer(i, key); Defensive patterns
Strategy: validation
Validate before calling
if (mapKey == null || isUnset(mapKey)) throw new IllegalArgumentException("map key must be bound to a concrete value"); Type guard
boolean isSet(ByteBuffer b) { return b != null && b != ByteBufferUtil.UNSET_BYTE_BUFFER; } Try / catch
try { session.execute(stmt); } catch (InvalidRequestException e) { if (e.getMessage().contains("unset map key")) rebuildQueryWithoutMapRestriction(); else throw e; } Prevention
- Never use setToUnset for map key parameters.
- Build the statement dynamically, omitting the restriction entirely when the key is unknown.
- Centralize statement binding so unset handling is uniform.
When it happens
Trigger: Executing `WHERE m[?] = ?` where the driver binds the key parameter as unset (e.g. unsetByteBuffer() / omitted named parameter), so columnsExpression.element(context) returns ByteBufferUtil.UNSET_BYTE_BUFFER.
Common situations: Drivers using named/unset parameter semantics (Java driver setToUnset) where callers skip a parameter assuming it is ignored; batch templates with optional map-key lookups left unset.
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
- Invalid null map key for column
- Invalid unset map key
- A TTL must be greater or equal to 0, but was
- Attempted to delete an element from a list which is null
- Cannot mix IF conditions and
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/a677721918bbdf40.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/restrictions/SimpleRestriction.java:458
// either directly or via filtering. If not, throw an error.
if (column.type.isFrozenCollection())
{
for (Index index : indexRegistry.listIndexes())
{
if (index.dependsOn(column)
&& !index.supportsMapElementExpression()
&& !index.supportsFilteringOnMapElementExpression())
{
throw invalidRequest(Relation.FROZEN_MAP_ENTRY_PREDICATES_NOT_SUPPORTED, column.name);
}
}
}
ByteBuffer key = columnsExpression.element(context);
if (key == null)
throw invalidRequest("Invalid null map key for column %s", column.name.toCQLString());
if (key == ByteBufferUtil.UNSET_BYTE_BUFFER)
throw invalidRequest("Invalid unset map key for column %s", column.name.toCQLString());
List<ByteBuffer> values = bindAndGet(context);
filter.addMapEquality(column, key, operator, values.get(0));
}
break;
default: throw new UnsupportedOperationException();
}
}
private static ByteBuffer multiInputOperatorValues(ColumnMetadata column, List<ByteBuffer> values)
{
return ListType.getInstance(column.type, false).pack(values);
}
@Override
public String toString()
{
return operator.buildCQLString(columnsExpression, values);
}View on GitHub (pinned to 88fd0f6a0e)