apache/cassandra · error · InvalidRequestException

Invalid null value for list index

Error message

Invalid null value for list index

What it means

InvalidRequestException from the list element setter's execute (Lists.IndexedSetter): a null value was bound for the list index used in an operation like lst[idx] = value on a non-frozen list. The index identifies which element to overwrite, so a null index cannot be resolved; the guard fires during execution after the read-before-write check on multi-cell lists.

Solutions

  1. Bind a non-null int index
  2. Compute/fail-fast the index in application code before executing
  3. If the element position is unknown, use a different list operation (append/preach whole-list set) instead of indexed set

Example fix

// before
ps.bind(0, index); // null
ps.bind(1, value);
// after
if (index != null) { ps.bind(0, index); ps.bind(1, value); }
Defensive patterns

Strategy: validation

Validate before calling

if (index == null) throw new IllegalArgumentException("list index required");

Try / catch

try { session.execute(ps.bind(idx, value)); } catch (InvalidQueryException e) { if (e.getMessage().contains("Invalid null value for list index")) { /* resolve index or skip */ } else throw e; }

Prevention

When it happens

Trigger: `UPDATE t SET l[?] = 'v'` executed with null bound to the index parameter.

Common situations: Index computed from user input or a lookup that returned null; DTO field for the index left unset and mapped to null by the driver.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/terms/Lists.java:364

        public void collectMarkerSpecification(VariableSpecifications boundNames, Object owner)
        {
            super.collectMarkerSpecification(boundNames, owner);
            idx.collectMarkerSpecification(boundNames, owner);
        }

        public void execute(DecoratedKey partitionKey, RowUpdateBuilder builder) throws InvalidRequestException
        {
            // we should not get here for frozen lists
            assert column.type.isMultiCell() : "Attempted to set an individual element on a frozen list";

            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);
        }
    }

View on GitHub (pinned to 88fd0f6a0e)