apache/cassandra · error · ConfigurationException
legacy_ssl_storage_port_enabled is true (enabled) with inter
Error message
legacy_ssl_storage_port_enabled is true (enabled) with internode encryption disabled (none). Enable encryption or disable the legacy ssl storage port.
What it means
The legacy SSL storage port option only makes sense when internode encryption is actually enabled. If server_encryption_options marks legacy_ssl_storage_port_enabled=true while tlsEncryptionPolicy() resolves to UNENCRYPTED (encryption set to 'none'), DatabaseDescriptor fails startup with this ConfigurationException telling you to either enable encryption or disable the legacy port.
Source
Thrown at src/java/org/apache/cassandra/config/DatabaseDescriptor.java:1198
case ssd:
diskOptimizationStrategy = new SsdDiskOptimizationStrategy(conf.disk_optimization_page_cross_chance);
break;
case spinning:
diskOptimizationStrategy = new SpinningDiskOptimizationStrategy();
break;
}
if (conf.compressed_read_ahead_buffer_size.toKibibytes() > 0 && conf.compressed_read_ahead_buffer_size.toKibibytes() < 256)
throw new ConfigurationException("compressed_read_ahead_buffer_size must be at least 256KiB (set to 0 to disable), but was " + conf.compressed_read_ahead_buffer_size, false);
if (conf.server_encryption_options != null)
{
conf.server_encryption_options.applyConfig();
if (conf.server_encryption_options.legacy_ssl_storage_port_enabled &&
conf.server_encryption_options.tlsEncryptionPolicy() == EncryptionOptions.TlsEncryptionPolicy.UNENCRYPTED)
{
throw new ConfigurationException("legacy_ssl_storage_port_enabled is true (enabled) with internode encryption disabled (none). Enable encryption or disable the legacy ssl storage port.");
}
}
if (conf.internode_max_message_size != null)
{
long maxMessageSize = conf.internode_max_message_size.toBytes();
if (maxMessageSize > conf.internode_application_receive_queue_reserve_endpoint_capacity.toBytes())
throw new ConfigurationException("internode_max_message_size must no exceed internode_application_receive_queue_reserve_endpoint_capacity", false);
if (maxMessageSize > conf.internode_application_receive_queue_reserve_global_capacity.toBytes())
throw new ConfigurationException("internode_max_message_size must no exceed internode_application_receive_queue_reserve_global_capacity", false);
if (maxMessageSize > conf.internode_application_send_queue_reserve_endpoint_capacity.toBytes())
throw new ConfigurationException("internode_max_message_size must no exceed internode_application_send_queue_reserve_endpoint_capacity", false);
if (maxMessageSize > conf.internode_application_send_queue_reserve_global_capacity.toBytes())
throw new ConfigurationException("internode_max_message_size must no exceed internode_application_send_queue_reserve_global_capacity", false);View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Set legacy_ssl_storage_port_enabled: false (or remove the option) if you don't need the legacy port
- Or enable encryption by setting internode_encryption (e.g. to dc/rack/all) in server_encryption_options
- Ensure the encryption options include valid keystore/truststore settings so the TLS policy is not UNENCRYPTED
Example fix
# before (cassandra.yaml) server_encryption_options: internode_encryption: none legacy_ssl_storage_port_enabled: true # after server_encryption_options: internode_encryption: dc legacy_ssl_storage_port_enabled: false
Defensive patterns
Strategy: validation
Validate before calling
if (conf.server_encryption_options.legacy_ssl_storage_port_enabled &&
conf.server_encryption_options.tlsEncryptionPolicy() == EncryptionOptions.TlsEncryptionPolicy.UNENCRYPTED)
throw new IllegalArgumentException("Enable internode encryption or disable legacy_ssl_storage_port_enabled"); Try / catch
try { DatabaseDescriptor.applyConfig(conf); } catch (ConfigurationException e) { if (e.getMessage().contains("legacy_ssl_storage_port_enabled")) { /* fix encryption options */ } } Prevention
- Only enable legacy_ssl_storage_port_enabled during migration with encryption actually on
- Verify internode_encryption is not 'none' when setting any SSL port option
- Audit server_encryption_options after upgrades that changed TLS defaults
When it happens
Trigger: cassandra.yaml has server_encryption_options with legacy_ssl_storage_port_enabled: true and internode_encryption: none (or an equivalent configuration that yields TlsEncryptionPolicy.UNENCRYPTED, e.g. missing enabled flag), during applySimpleConfig.
Common situations: Upgrades from very old clusters that used ssl_storage_port; operators enabling the legacy flag 'for later' but leaving encryption off; comment-removal in yaml that re-enables the flag without setting internode_encryption.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Unrecognized TLS encryption policy:
- Setting server_encryption_options.enabled has no effect, use
- Load CIDR groups cache operation not supported by %s
- Unsupported parameter '%s' for %s, supported parameters are
- Configured node identity is not matching identity extractedf
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/0637db72d1601fb2.
Report an issue: GitHub.