apache/cassandra · error · InvalidRequestException
Invalid empty or null value for column
Error message
Invalid empty or null value for column %s
What it means
In RowUpdateBuilder.newRow, for COMPACT STORAGE tables with a single clustering column, an empty or null clustering value is rejected even though the storage engine could technically represent it, for backward compatibility with the thrift-era behavior where the compact value could not be empty.
Solutions
- Supply a non-empty value for the single clustering column
- Skip rows whose clustering value is null/empty instead of building an update
- Migrate the table off COMPACT STORAGE (ALTER ... WITH COMPACT STORAGE removal / re-create as regular table) where empty clustering is valid
- Validate clustering values before calling newRow
Example fix
// before builder.newRow(clustering); // clustering.get(0) is empty byte buffer // after if (value == null || accessor.isEmpty(value)) return; // skip or fix value builder.newRow(clustering);
Defensive patterns
Strategy: validation
Validate before calling
if (clusteringValue == null || clusteringValue.remaining() == 0)
throw new IllegalArgumentException("clustering value required for COMPACT STORAGE table"); Try / catch
try { builder.newRow(key).add(...); } catch (InvalidRequestException e) { if (e.getMessage().startsWith("Invalid empty or null value for column")) skipOrFixRow(); else throw e; } Prevention
- Validate clustering components before building updates
- Skip or repair source records with empty keys during migrations
- Prefer regular (non-COMPACT STORAGE) tables for new schemas
When it happens
Trigger: Calling newRow() (directly or via addRow/applyUpdates) on a COMPACT STORAGE table whose single clustering column receives null or a zero-length value.
Common situations: Writing rows to legacy thrift-created COMPACT STORAGE tables from CQL/internal APIs with missing clustering values; deserializing records where the clustering component is absent; tests building updates with placeholder empty keys.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Cannot add new column to a COMPACT STORAGE table
- Cannot create ENTRIES index on frozen map clustering column
- Cannot create materialized view
- Cannot DROP COMPACT STORAGE as some nodes in the cluster
- Clustering key columns must exactly match columns in…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/19c7155e2f14ad74.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/RowUpdateBuilder.java:129
@Override
public QueryOptions options()
{
return options;
}
public <V> void newRow(Clustering<V> clustering) throws InvalidRequestException
{
if (metadata.isCompactTable())
{
if (TableMetadata.Flag.isDense(metadata.flags) && !TableMetadata.Flag.isCompound(metadata.flags))
{
// If it's a COMPACT STORAGE table with a single clustering column and for backward compatibility we
// don't want to allow that to be empty (even though this would be fine for the storage engine).
assert clustering.size() == 1 : clustering.toString(metadata);
V value = clustering.get(0);
if (value == null || clustering.accessor().isEmpty(value))
throw new InvalidRequestException("Invalid empty or null value for column " + metadata.clusteringColumns().get(0).name);
}
}
assert builder == null : "newRow called without building the previous row";
builder = BTreeRow.pooledUnsortedBuilder();
builder.newRow(clustering);
}
public Clustering<?> currentClustering()
{
return builder.clustering();
}
public void addPrimaryKeyLivenessInfo()
{
addPrimaryKeyLivenessInfo(LivenessInfo.create(timestamp, ttl, nowInSec));
}
private void addPrimaryKeyLivenessInfo(LivenessInfo info)View on GitHub (pinned to 88fd0f6a0e)