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

  1. Supply a non-empty value for the single clustering column
  2. Skip rows whose clustering value is null/empty instead of building an update
  3. Migrate the table off COMPACT STORAGE (ALTER ... WITH COMPACT STORAGE removal / re-create as regular table) where empty clustering is valid
  4. 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

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


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)