apache/cassandra · error · ConfigurationException

Fan factor cannot be lower than 2 in %s

Error message

Fan factor cannot be lower than 2 in %s

What it means

In UCS scaling parameters, the n in an 'L+n' expression is a fan factor (how many sstables are merged per level) and must be at least 2. atLeast2 throws ConfigurationException when a smaller value is given, so 'L+0' and 'L+1' are rejected.

Source

Thrown at src/java/org/apache/cassandra/db/compaction/UnifiedCompactionStrategy.java:139

    {
        Matcher m = SCALING_PARAMETER_PATTERN.matcher(value);
        if (!m.matches())
            throw new ConfigurationException("Scaling parameter " + value + " must match " + SCALING_PARAMETER_PATTERN_SIMPLIFIED);

        if (m.group(1) != null)
            return 0;
        else if (m.group(2) != null)
            return 2 - atLeast2(Integer.parseInt(m.group(2)), value);
        else if (m.group(3) != null)
            return atLeast2(Integer.parseInt(m.group(3)), value) - 2;
        else
            return Integer.parseInt(m.group(4));
    }

    private static int atLeast2(int value, String str)
    {
        if (value < 2)
            throw new ConfigurationException("Fan factor cannot be lower than 2 in " + str);
        return value;
    }

    public static String printScalingParameter(int w)
    {
        if (w < 0)
            return 'L' + Integer.toString(2 - w);
        else if (w > 0)
            return 'T' + Integer.toString(w + 2);
        else
            return "N";
    }

    private TimeUUID nextTimeUUID()
    {
        // Make a time-UUID with sequence 0. The reason to do this is to accommodate parallelized compactions:
        // - Sequence 0 (visible as -8000- in the UUID string) denotes single-task (i.e. non-parallelized) compactions.
        // - Sequence >0 (-800n-) denotes the individual task's index of a parallelized compaction.

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Use n >= 2 in the L+n expression, e.g. 'L+2'
  2. If a linear single-threaded shape was intended, use a plain numeric scaling value instead of L+n
  3. Catch ConfigurationException around table option application
  4. Review UCS tuning guidance: fan factor controls overlap of accepted overlaps O = W/2^(n-1)

Example fix

// before
'scaling_wainer': 'L+1'
// after
'scaling_wainer': 'L+2'
Defensive patterns

Strategy: validation

Validate before calling

if (opts.containsKey("scaling_wainer") && opts.get("scaling_wainer").matches("L\\+\\d+")) {
    int n = Integer.parseInt(opts.get("scaling_wainer").substring(2));
    if (n < 2) throw new IllegalArgumentException("L+n fan factor must be >= 2");
}

Type guard

static boolean isLPlusValid(String s) { return s != null && s.matches("L\\+\\d+") && Integer.parseInt(s.substring(2)) >= 2; }

Try / catch

try {
    session.execute(alterStmt);
} catch (RuntimeException e) {
    if (e.getMessage().contains("Fan factor cannot be lower than 2")) { /* bump n and retry */ }
    throw e;
}

Prevention

When it happens

Trigger: parseScalingParameter called with an 'L+n' scaling parameter where n < 2, e.g. 'L+1', 'L+0'; triggered from validateOptions/table creation with UnifiedCompactionStrategy options.

Common situations: Modeling single-splits by writing L+1 (a fan factor of 1 means no fan-out and is invalid); off-by-one mistakes in tuned compaction setups.

Related errors


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