apache/cassandra · error · InvalidRequestException
List index out of bound, list has size
Error message
List index %d out of bound, list has size %d
What it means
Thrown when the index used in a list element assignment is outside the bounds of the existing list (negative, or >= current size). Lists in Cassandra are cell-indexed by their existing element paths; you can only overwrite existing positions, not grow via index.
Solutions
- Fetch the list first and validate 0 <= index < size before the indexed update
- Use list append (l = l + [...]) to grow, or rewrite the whole list, instead of out-of-range indexes
- Re-read the list after concurrent mutations before computing the index
Example fix
// before int idx = list.size(); // off-by-one, out of bounds UPDATE t SET l[idx] = 'v'; // after int idx = list.size() - 1; if (idx >= 0) UPDATE t SET l[idx] = 'v';
Defensive patterns
Strategy: validation
Validate before calling
List<String> l = row.getList("l", String.class); if (idx < 0 || idx >= l.size()) throw new IndexOutOfBoundsException("idx=" + idx + " size=" + l.size()); Try / catch
try { session.execute(stmt); } catch (InvalidQueryException e) { if (e.getMessage().contains("List index") && e.getMessage().contains("out of bound")) { /* re-read list and recompute index */ } else throw e; } Prevention
- Read the list immediately before indexed writes
- Use size-1 not size for last element
- Handle concurrency: lists can shrink between read and write
When it happens
Trigger: `UPDATE t SET l[5] = 'v'` when l has 2 elements; any negative index; index computed from stale client-side data after concurrent writes shrunk the list.
Common situations: Off-by-one errors (using size instead of size-1); stale UI index after list mutation; assuming CQL lists behave like zero-padded arrays.
Related errors
- Attempted to delete an element from a list which is null
- Attempted to set an element on a list which is null
- Invalid null value for list index
- Invalid unset value for list index
- selection is only allowed on sets and maps, but is a list
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/feab6fb11328d29c.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/terms/Lists.java:374
Guardrails.readBeforeWriteListOperationsEnabled
.ensureEnabled("Setting of list items by index requiring read before write", builder.clientState);
ByteBuffer index = idx.bindAndGet(builder);
ByteBuffer value = t.bindAndGet(builder);
if (index == null)
throw new InvalidRequestException("Invalid null value for list index");
if (index == ByteBufferUtil.UNSET_BYTE_BUFFER)
throw new InvalidRequestException("Invalid unset value for list index");
Row existingRow = builder.getPrefetchedRow(partitionKey, builder.currentClustering());
int existingSize = existingSize(existingRow, column);
int idx = ByteBufferUtil.toInt(index);
if (existingSize == 0)
throw new InvalidRequestException("Attempted to set an element on a list which is null");
if (idx < 0 || idx >= existingSize)
throw new InvalidRequestException(String.format("List index %d out of bound, list has size %d", idx, existingSize));
CellPath elementPath = existingRow.getComplexColumnData(column).getCellByIndex(idx).path();
if (value == null)
builder.addTombstone(column, elementPath);
else if (value != ByteBufferUtil.UNSET_BYTE_BUFFER)
builder.addCell(column, elementPath, value);
}
}
public static class Appender extends Operation
{
public Appender(ColumnMetadata column, Term t)
{
super(column, t);
}
public void execute(DecoratedKey partitionKey, RowUpdateBuilder builder) throws InvalidRequestException
{View on GitHub (pinned to 88fd0f6a0e)