apache/cassandra · error · ConfigurationException

%s must not be negative, but was %d

Error message

%s must not be negative, but was %d

What it means

TWCS rejects a negative expired_sstable_check_frequency_seconds option. This option controls how often (in seconds) the strategy checks for fully expired sstables; a negative interval is meaningless, so validateOptions throws ConfigurationException with the offending key and parsed value.

Source

Thrown at src/java/org/apache/cassandra/db/compaction/TimeWindowCompactionStrategyOptions.java:142

        {
            int sstableWindowSize = optionValue == null ? DEFAULT_COMPACTION_WINDOW_SIZE : Integer.parseInt(optionValue);
            if (sstableWindowSize < 1)
            {
                throw new ConfigurationException(String.format("%d must be greater than 1 for %s", sstableWindowSize, COMPACTION_WINDOW_SIZE_KEY));
            }
        }
        catch (NumberFormatException e)
        {
            throw new ConfigurationException(String.format("%s is not a parsable int (base10) for %s", optionValue, COMPACTION_WINDOW_SIZE_KEY), e);
        }

        optionValue = options.get(EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS_KEY);
        try
        {
            long expiredCheckFrequency = optionValue == null ? DEFAULT_EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS : Long.parseLong(optionValue);
            if (expiredCheckFrequency < 0)
            {
                throw new ConfigurationException(String.format("%s must not be negative, but was %d", EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS_KEY, expiredCheckFrequency));
             }
        }
        catch (NumberFormatException e)
        {
            throw new ConfigurationException(String.format("%s is not a parsable int (base10) for %s", optionValue, EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS_KEY), e);
        }


        optionValue = options.get(UNSAFE_AGGRESSIVE_SSTABLE_EXPIRATION_KEY);
        if (optionValue != null)
        {
            if (!(optionValue.equalsIgnoreCase("true") || optionValue.equalsIgnoreCase("false")))
                throw new ConfigurationException(String.format("%s is not 'true' or 'false' (%s)", UNSAFE_AGGRESSIVE_SSTABLE_EXPIRATION_KEY, optionValue));

            if (optionValue.equalsIgnoreCase("true") && !UNSAFE_AGGRESSIVE_SSTABLE_EXPIRATION_ENABLED)
                throw new ConfigurationException(String.format("%s is requested but not allowed, restart cassandra with -D%s=true to allow it",
                                                               UNSAFE_AGGRESSIVE_SSTABLE_EXPIRATION_KEY, ALLOW_UNSAFE_AGGRESSIVE_SSTABLE_EXPIRATION.getKey()));
        }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Change the value to a non-negative integer, e.g. '600' (seconds)
  2. Use 0 to disable expired sstable checks entirely
  3. Remove the option to fall back to the default (600 seconds)
  4. Catch ConfigurationException when validating user-supplied table options

Example fix

// before
{'class':'TimeWindowCompactionStrategy','expired_sstable_check_frequency_seconds':'-60'}
// after
{'class':'TimeWindowCompactionStrategy','expired_sstable_check_frequency_seconds':'600'}
Defensive patterns

Strategy: validation

Validate before calling

if (opts.containsKey("expired_sstable_check_frequency_seconds") && Long.parseLong(opts.get("expired_sstable_check_frequency_seconds")) < 0)
    throw new IllegalArgumentException("expired_sstable_check_frequency_seconds must be >= 0");

Type guard

static boolean isNonNegativeLong(String s) { if (s == null) return false; try { return Long.parseLong(s.trim()) >= 0; } catch (NumberFormatException e) { return false; } }

Try / catch

try {
    session.execute(alterStmt);
} catch (RuntimeException e) {
    if (e.getMessage().contains("must not be negative")) { /* fix value and retry */ }
    throw e;
}

Prevention

When it happens

Trigger: validateOptions invoked with expired_sstable_check_frequency_seconds set to a negative long, e.g. '-60' (a non-numeric value triggers error 882 instead).

Common situations: Signing a value meant to be a timestamp offset; blindly templating '-1' as a sentinel for 'disabled' (wrong option — 0 disables it); typos like an accidental minus sign.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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