Guardrails Reference
|
Preview | Unofficial | For review only |
Guardrails are configurable safeguards that warn operators or reject operations before they can destabilize a cluster.
Each guardrail has a property in conf/cassandra.yaml and is dynamically configurable at runtime via JMX (GuardrailsMBean).
Cassandra 6 introduces several new guardrails and extends existing ones with finer-grained controls. This page documents the guardrails introduced or significantly changed for Cassandra 6.
|
Guardrail types used in this reference
|
Bulk Loading
Source: CASSANDRA-18781 (JIRA)
Implementation: Guardrails.bulkLoadEnabled (EnableFlag)
Enforcement point: StreamDeserializingTask — evaluated when an incoming streaming session has operation type StreamOperation.BULK_LOAD
Settings
Property (cassandra.yaml) |
Type | Default | Description |
|---|---|---|---|
|
boolean |
|
When |
Operational notes
-
This guardrail uses
.throwOnNullClientState(true), which means it is enforced even when there is no CQL client session context. Streaming operations do not carry a traditional client state, so this ensures the guardrail cannot be bypassed by streaming. -
The warning message logged when this guardrail fires is:
"Bulk loading of SSTables might potentially destabilize the node." -
Unlike most guardrails, which exempt superuser or internal operations, this guardrail applies cluster-wide regardless of caller context.
-
Default is
true(bulk loading permitted), so no behavioral change on upgrade. To restrict bulk loading, setbulk_load_enabled: falseincassandra.yamlor via JMX. -
nodetool importdoes not trigger this guardrail.nodetool importloads SSTables locally via JMX (SSTableImporter) without streaming; it does not useStreamOperation.BULK_LOAD. Onlysstableloader, which streams SSTables to the cluster, usesBULK_LOADand is therefore affected.
Keyspace DDL Properties
Source: CASSANDRA-20913 (JIRA)
Implementation: Guardrails.keyspaceProperties (Values<String>)
Enforcement points: CreateKeyspaceStatement.validate() and AlterKeyspaceStatement.validate()
This guardrail allows operators to warn about, silently strip, or disallow specific keyspace properties in CREATE KEYSPACE and ALTER KEYSPACE statements.
The primary use case is preventing durable_writes = false, which disables the commitlog and risks data loss on node crash, but the guardrail is generic and supports any recognized keyspace property name.
The design mirrors the existing table_properties_warned/ignored/disallowed guardrail pattern.
Settings
Property (cassandra.yaml) |
Type | Default | Description |
|---|---|---|---|
|
|
|
Property names that trigger a client warning when used in |
|
|
|
Property names that are silently stripped from |
|
|
|
Property names that cause |
Operational notes
-
All three sets default to empty, so there is no behavioral change on upgrade. Operators must explicitly configure these settings to restrict keyspace properties.
-
Precedence: Disallowed takes precedence over warned if a property name appears in both sets.
-
Validation rules:
-
Property names are automatically lowercased when the configuration is validated.
-
Null values are rejected in all three sets.
-
Required keyspace keywords — specifically
replication— cannot be placed in any of the three lists (keyspace_properties_warned,keyspace_properties_ignored, orkeyspace_properties_disallowed). Attempting to addreplicationto any list throws anIllegalArgumentExceptionduring configuration validation because it is a required keyspace property. -
Only recognized keyspace property names (from
KeyspaceAttributes.allKeywords()) are accepted in configuration.
-
-
Settings are dynamically configurable at runtime via JMX, with both
Set<String>and CSV accessor variants.
Example configuration
# Disallow creation or modification of keyspaces with durable_writes = false
keyspace_properties_disallowed:
- durable_writes
# Warn when durable_writes = false is used, but do not reject
keyspace_properties_warned:
- durable_writes
The complete list of valid keyspace property names (from KeyspaceAttributes.allKeywords()) is: durable_writes, replication, and fast_path.
Disk Usage
Source: CASSANDRA-21024 (JIRA)
Implementation: Guardrails.diskUsageKeyspaceWideProtection (Predicates<String>)
Enforcement point: ModificationStatement.validateDiskUsage()
Cassandra 6 extends the existing per-replica disk usage guardrail with a new keyspace-wide protection mode. When enabled, writes to a keyspace are rejected if any node in any datacenter replicating that keyspace exceeds the disk usage failure threshold, not just the specific replicas that would handle a given write.
This prevents cascading failures where writes redirected away from full nodes overload the remaining nodes.
Full disk usage settings (including pre-existing settings)
Property (cassandra.yaml) |
Type | Default | Description |
|---|---|---|---|
|
integer (percentage) |
|
Disk usage percentage at which a node is considered "stuffed" (warn-level). Writes targeting replicas on a stuffed node generate a client warning. Used by both the per-replica guardrail and the keyspace-wide protection feature. |
|
integer (percentage) |
|
Disk usage percentage at which a node is considered "full" (fail-level). Writes targeting replicas on a full node are rejected. Used by both the per-replica guardrail and the keyspace-wide protection feature. |
|
data storage size |
(unset) |
Optional cap on the disk size used in threshold calculations. If set, thresholds are applied against this value rather than the actual disk capacity. |
|
boolean |
|
New in Cassandra 6.
When |
Operational notes
-
data_disk_usage_keyspace_wide_protection_enableddefaults tofalseand has no effect unlessdata_disk_usage_percentage_fail_thresholdis also set to a positive value. Whenfail_thresholdis-1, the failure check is disabled (the threshold becomesLong.MAX_VALUE, which can never be exceeded); only the warn threshold applies. Therefore, enabling keyspace-wide protection withfail_threshold: -1has no practical effect — writes are never rejected. -
When keyspace-wide protection is enabled and the fail threshold is exceeded on any node:
-
For keyspaces using
NetworkTopologyStrategy: only datacenters where the keyspace is actually replicated are checked. -
For keyspaces using
SimpleStrategy: all known datacenters are checked.
-
-
Per-datacenter disk state (stuffed/full) is tracked in
DiskUsageBroadcasterusing gossip state changes. Datacenter membership is resolved via TCM (Transactional Cluster Metadata)LocatorandLocationinterfaces. -
When keyspace-wide protection is disabled, the original per-replica
replicaDiskUsageguardrail remains active and is unaffected by this setting. -
Setting is dynamically configurable at runtime via JMX (
GuardrailsMBean). -
The exact client error message when a write is rejected by keyspace-wide disk protection is:
"Write request failed because disk usage exceeds failure threshold in <keyspace> <datacenter>."
Example configuration
# Existing disk usage thresholds (required for keyspace-wide protection to take effect)
data_disk_usage_percentage_warn_threshold: 70
data_disk_usage_percentage_fail_threshold: 90
# Enable keyspace-wide write rejection when any replicating node is full
data_disk_usage_keyspace_wide_protection_enabled: true
Interaction between disk usage guardrails
| Setting | Mode | Behavior when fail_threshold exceeded |
|---|---|---|
|
Per-replica (default) |
Writes rejected only when the specific partition replicas are on full nodes. |
|
Keyspace-wide |
All writes to the keyspace rejected when any node in a replicating datacenter is full, regardless of which replicas would handle the specific write. |
Per-Type Size Limits
Source: CASSANDRA-19677 (JIRA)
Implementation: columnAsciiValueSize, columnBlobValueSize, columnTextAndVarcharValueSize (MaxThreshold);
collectionMapSize, collectionSetSize, collectionListSize (FallbackThreshold<MaxThreshold>)
Enforcement points: UpdateParameters.validateColumnSize() (column types); Lists.java, Maps.java, Sets.java (collection types)
Cassandra 6 adds type-specific size guardrails as a refinement of the existing generic column_value_size and collection_size guardrails.
Operators can now set different warn and fail thresholds per column type (ascii, blob, text/varchar) and per collection type (map, set, list).
This is useful for workloads with mixed data types — for example, allowing large binary blobs while restricting text column sizes, or applying tighter limits to lists than to maps.
Column-type-specific value size guardrails
Property (cassandra.yaml) |
Type | Default | Description |
|---|---|---|---|
|
data storage size |
(unset / null) |
Size above which a write to an |
|
data storage size |
(unset / null) |
Size above which a write to an |
|
data storage size |
(unset / null) |
Size above which a write to a |
|
data storage size |
(unset / null) |
Size above which a write to a |
|
data storage size |
(unset / null) |
Size above which a write to a |
|
data storage size |
(unset / null) |
Size above which a write to a |
|
Interaction with the generic
column_value_size guardrailWhen a type-specific column size guardrail is configured alongside the generic The fail threshold is checked first. If it is exceeded, the operation is aborted immediately without also triggering a warning. |
-
Column-type-specific guardrails apply to regular column values only. Partition key and clustering key components have a fixed 65535-byte limit enforced separately.
-
All thresholds default to null (disabled). When null, the guardrail has no effect for that type; the generic
column_value_sizeguardrail still applies. -
All thresholds are dynamically configurable via JMX.
Collection-type-specific size guardrails
Property (cassandra.yaml) |
Type | Default | Description |
|---|---|---|---|
|
data storage size |
(unset / null) |
Size above which a write to a |
|
data storage size |
(unset / null) |
Size above which a write to a |
|
data storage size |
(unset / null) |
Size above which a write to a |
|
data storage size |
(unset / null) |
Size above which a write to a |
|
data storage size |
(unset / null) |
Size above which a write to a |
|
data storage size |
(unset / null) |
Size above which a write to a |
|
FallbackThreshold behavior for collection-type guardrails
Collection-type-specific guardrails use a This differs from column-type-specific guardrails, which are independent |
-
At SSTable write time, collection size guardrails only apply to non-frozen (multi-cell) collections; frozen collections are skipped entirely. At this stage, exceeding the fail threshold logs an error but does not abort the write operation. At CQL write time, both frozen and non-frozen collections are checked.
-
All thresholds default to null (disabled) and are dynamically configurable via JMX.
Example configuration
# Allow larger blobs than text; restrict ASCII tightly
column_ascii_value_size_warn_threshold: 64KiB
column_ascii_value_size_fail_threshold: 128KiB
column_blob_value_size_warn_threshold: 10MiB
column_blob_value_size_fail_threshold: 50MiB
column_text_and_varchar_value_size_warn_threshold: 1MiB
column_text_and_varchar_value_size_fail_threshold: 5MiB
# Type-specific collection limits
collection_map_size_warn_threshold: 1MiB
collection_map_size_fail_threshold: 5MiB
collection_set_size_warn_threshold: 1MiB
collection_set_size_fail_threshold: 5MiB
collection_list_size_warn_threshold: 1MiB
collection_list_size_fail_threshold: 5MiB
Accepted size units for DataStorageSpec.LongBytesBound fields are B, KiB, MiB, and GiB (case-sensitive, binary prefixes only).
Dynamic Reconfiguration via JMX
All guardrails documented on this page are dynamically configurable at runtime without a node restart.
The JMX interface is GuardrailsMBean in org.apache.cassandra.db.guardrails.
Changes made via JMX persist only for the lifetime of the JVM process.
To make a change permanent, update cassandra.yaml on each node.
Use nodetool getguardrailsconfig to view current guardrail settings.
The optional --category flag filters output by category: values, thresholds, flags, or others.
Use nodetool setguardrailsconfig to modify guardrail settings at runtime.
Resolved Research Notes
The following questions were resolved by source verification against the trunk branch of apache/cassandra:
-
Bulk loading:
nodetool importdoes not useStreamOperation.BULK_LOAD; it loads SSTables locally via JMX (SSTableImporter). Onlysstableloadertriggers this guardrail. -
Keyspace properties — valid names:
KeyspaceAttributes.allKeywords()returnsdurable_writes,replication, andfast_path. -
Keyspace properties — replication restriction:
replicationcannot appear in any of the three guardrail lists (warned, ignored, disallowed). Adding it throwsIllegalArgumentException. -
Disk usage — fail threshold at -1: When
fail_thresholdis-1, it resolves toLong.MAX_VALUE, effectively disabling the failure check. Keyspace-wide protection has no effect without a positive fail threshold. -
Disk usage — client error message: The rejection message is
"Write request failed because disk usage exceeds failure threshold in <keyspace> <datacenter>.". -
Column-type guardrails — evaluation order: The fail threshold is checked first; if exceeded, the operation is aborted immediately without triggering a warning.
-
Collection-type guardrails — frozen collections: At SSTable write time, only non-frozen (multi-cell) collections are checked; frozen collections are skipped. At CQL write time, both are checked.
-
Size unit format: Accepted units are
B,KiB,MiB, andGiB(case-sensitive, binary prefixes only). -
Nodetool commands:
nodetool getguardrailsconfig(with optional--categoryflag forvalues/thresholds/flags/others) andnodetool setguardrailsconfig.
Related Pages
-
Operating Cassandra — operator overview
-
Configuration Reference — full
cassandra.yamlproperty reference -
CQL Data Definition —
CREATE KEYSPACEandALTER KEYSPACEsyntax reference