{"record":{"id":"fa6a5eb3fa7f57e8","repo":"apache/cassandra","slug":"fan-factor-cannot-be-lower-than-2-in-s","errorCode":null,"errorMessage":"Fan factor cannot be lower than 2 in %s","messagePattern":"Fan factor cannot be lower than 2 in (.+?)","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/compaction/UnifiedCompactionStrategy.java","lineNumber":139,"sourceCode":"    {\n        Matcher m = SCALING_PARAMETER_PATTERN.matcher(value);\n        if (!m.matches())\n            throw new ConfigurationException(\"Scaling parameter \" + value + \" must match \" + SCALING_PARAMETER_PATTERN_SIMPLIFIED);\n\n        if (m.group(1) != null)\n            return 0;\n        else if (m.group(2) != null)\n            return 2 - atLeast2(Integer.parseInt(m.group(2)), value);\n        else if (m.group(3) != null)\n            return atLeast2(Integer.parseInt(m.group(3)), value) - 2;\n        else\n            return Integer.parseInt(m.group(4));\n    }\n\n    private static int atLeast2(int value, String str)\n    {\n        if (value < 2)\n            throw new ConfigurationException(\"Fan factor cannot be lower than 2 in \" + str);\n        return value;\n    }\n\n    public static String printScalingParameter(int w)\n    {\n        if (w < 0)\n            return 'L' + Integer.toString(2 - w);\n        else if (w > 0)\n            return 'T' + Integer.toString(w + 2);\n        else\n            return \"N\";\n    }\n\n    private TimeUUID nextTimeUUID()\n    {\n        // Make a time-UUID with sequence 0. The reason to do this is to accommodate parallelized compactions:\n        // - Sequence 0 (visible as -8000- in the UUID string) denotes single-task (i.e. non-parallelized) compactions.\n        // - Sequence >0 (-800n-) denotes the individual task's index of a parallelized compaction.","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/compaction/UnifiedCompactionStrategy.java#L121-L157","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before\n'scaling_wainer': 'L+1'\n// after\n'scaling_wainer': 'L+2'","handlingStrategy":"validation","validationCode":"if (opts.containsKey(\"scaling_wainer\") && opts.get(\"scaling_wainer\").matches(\"L\\\\+\\\\d+\")) {\n    int n = Integer.parseInt(opts.get(\"scaling_wainer\").substring(2));\n    if (n < 2) throw new IllegalArgumentException(\"L+n fan factor must be >= 2\");\n}","typeGuard":"static boolean isLPlusValid(String s) { return s != null && s.matches(\"L\\\\+\\\\d+\") && Integer.parseInt(s.substring(2)) >= 2; }","tryCatchPattern":"try {\n    session.execute(alterStmt);\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"Fan factor cannot be lower than 2\")) { /* bump n and retry */ }\n    throw e;\n}","preventionTips":["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"],"tags":["cassandra","configuration","compaction","ucs","validation"],"backgroundTag":"argument-out-of-range","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}