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
- Use n >= 2 in the L+n expression, e.g. 'L+2'
- If a linear single-threaded shape was intended, use a plain numeric scaling value instead of L+n
- Catch ConfigurationException around table option application
- 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
- Remember fan factor is merges per level; it starts at 2
- Prefer plain numeric scaling values unless modeling L(n) overlap shapes
- Validate L+n parameters in tooling before schema changes
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
- Scaling parameter %s must match %s
- Invalid configuration, %s should be positive: %d
- %s is not a parsable int (base10) for %s
- %s %s is out of range of Long.
- %s %s is not acceptable, size must be at least %s
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/fa6a5eb3fa7f57e8.
Report an issue: GitHub.