apache/cassandra · error · ConfigurationException

Configure either jmx_server_options in cassandra.yaml and co

Error message

Configure either jmx_server_options in cassandra.yaml and comment out configure_jmx function call in cassandra-env.sh or keep cassandra-env.sh to call configure_jmx function but you have to keep jmx_server_options in cassandra.yaml commented out.

What it means

JMX can be configured in exactly one of two ways: via jmx_server_options in cassandra.yaml, or via the configure_jmx function called from cassandra-env.sh (which reads system properties). DatabaseDescriptor throws this ConfigurationException when both are present at once — jmx_server_options is defined in yaml AND JMXServerOptions.isEnabledBySystemProperties() detects the configure_jmx system properties — because the two configurations would conflict.

Source

Thrown at src/java/org/apache/cassandra/config/DatabaseDescriptor.java:1161

                throw new ConfigurationException("native_transport_max_message_size must not exceed native_transport_max_request_data_in_flight", false);

            if (maxCqlMessageSize > conf.native_transport_max_request_data_in_flight_per_ip.toBytes())
                throw new ConfigurationException("native_transport_max_message_size must not exceed native_transport_max_request_data_in_flight_per_ip", false);

        }
        nativeTransportMaxMessageSizeInBytes = conf.native_transport_max_message_size.toBytes();

        // native transport encryption options
        if (conf.client_encryption_options != null)
            conf.client_encryption_options.applyConfig();

        if (conf.jmx_server_options == null)
        {
            conf.jmx_server_options = JMXServerOptions.createParsingSystemProperties();
        }
        else if (JMXServerOptions.isEnabledBySystemProperties())
        {
                throw new ConfigurationException("Configure either jmx_server_options in cassandra.yaml and comment out " +
                                                 "configure_jmx function call in cassandra-env.sh or keep cassandra-env.sh " +
                                                 "to call configure_jmx function but you have to keep jmx_server_options " +
                                                 "in cassandra.yaml commented out.");
        }

        conf.jmx_server_options.jmx_encryption_options.applyConfig();

        if (conf.snapshot_links_per_second < 0)
            throw new ConfigurationException("snapshot_links_per_second must be >= 0");

        if (conf.max_value_size.toMebibytes() == 0)
            throw new ConfigurationException("max_value_size must be positive", false);
        else if (conf.max_value_size.toMebibytes() >= 2048)
            throw new ConfigurationException("max_value_size must be smaller than 2048, but was "
                                             + conf.max_value_size.toString(), false);

        switch (conf.disk_optimization_strategy)
        {

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Comment out the configure_jmx call in conf/cassandra-env.sh (keeping jmx_server_options in cassandra.yaml)
  2. Or comment out the jmx_server_options block in cassandra.yaml and keep using configure_jmx in cassandra-env.sh
  3. Remove leftover JMX_REMOTE/COM_SUN_MANAGEMENT related system properties if configure_jmx was inlined elsewhere

Example fix

# before (cassandra-env.sh)
JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.remote.port=7199"
configure_jmx
# after
# configure_jmx  # jmx_server_options is used in cassandra.yaml instead
Defensive patterns

Strategy: validation

Validate before calling

boolean yamlHasJmx = conf.jmx_server_options != null;
boolean envHasJmx = System.getProperty("cassandra.jmx.remote.port") != null;
if (yamlHasJmx && envHasJmx) throw new IllegalStateException("Use either jmx_server_options or configure_jmx, not both");

Try / catch

try { DatabaseDescriptor.applyConfig(conf); } catch (ConfigurationException e) { if (e.getMessage().contains("jmx_server_options")) { /* disable one JMX mechanism */ } }

Prevention

When it happens

Trigger: cassandra.yaml contains a non-null jmx_server_options block while cassandra-env.sh still calls configure_jmx (leaving jmx remote access / authentication system properties set), and DatabaseDescriptor.applySimpleConfig runs at startup.

Common situations: Admins editing cassandra.yaml to move JMX config into yaml but forgetting to comment out the configure_jmx call in cassandra-env.sh; automated images bundling both mechanisms; docs/tutorials from different Cassandra versions recommending different mechanisms.

Related errors


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