{"record":{"id":"92376e5de9273e2a","repo":"apache/cassandra","slug":"invalid-to-specify-an-absolute-maximum-constant-wh","errorCode":null,"errorMessage":"Invalid to specify an absolute maximum constant when the max bound is itself a constant: '${original}'","messagePattern":"Invalid to specify an absolute maximum constant when the max bound is itself a constant: '(.+?)'","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/RetryStrategy.java","lineNumber":320,"sourceCode":"\n        Matcher m = PARSE.matcher(spec);\n        if (!m.matches())\n            throw new IllegalArgumentException(\"Invalid specification: '\" + spec + \"'; does not match \" + PARSE);\n\n        long minMin = parseInMicros(m.group(\"minmin\"), 0);\n        long maxMax = parseInMicros(m.group(\"maxmax\"), Long.MAX_VALUE);\n        Wait max = TimeoutStrategy.parseWait(m.group(\"max\"), latencies);\n        String minSpec = m.group(\"min\");\n        Wait min = minSpec == null ? null : TimeoutStrategy.parseWait(minSpec, latencies);\n        if (min == null && randomizer != null)\n            throw new IllegalArgumentException(\"Invalid to specify randomiser when no range specified: '\" + original + '\\'');\n        if (min instanceof Wait.Constant && minMin != 0)\n            throw new IllegalArgumentException(\"Invalid to specify an absolute minimum constant when the min bound is itself a constant: '\" + original + '\\'');\n        long maxMin = parseInMicros(m.group(\"maxmin\"), Long.MAX_VALUE);\n        if (min instanceof Wait.Constant && maxMin != Long.MAX_VALUE)\n            throw new IllegalArgumentException(\"Invalid to specify an absolute max(min) constant when the min bound is itself a constant: '\" + original + '\\'');\n        if (max instanceof Wait.Constant && maxMax != Long.MAX_VALUE)\n            throw new IllegalArgumentException(\"Invalid to specify an absolute maximum constant when the max bound is itself a constant: '\" + original + '\\'');\n        if (randomizer == null)\n            randomizer = randomizers.uniform();\n        return new RetryStrategy(randomizer, minMin, min, maxMin, max, maxMax, retries);\n    }\n\n    @VisibleForTesting\n    protected static WaitRandomizer parseWaitRandomizer(String input)\n    {\n        Matcher m = RANDOMIZER.matcher(input);\n        if (!m.matches())\n            throw new IllegalArgumentException(input + \" does not match\" + RANDOMIZER);\n\n        String exp;\n        exp = m.group(\"exp\");\n        if (exp != null)\n            return randomizers.exponential(Double.parseDouble(exp));\n        exp = m.group(\"qexp\");\n        if (exp != null)","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/RetryStrategy.java#L302-L338","documentation":"The maxmax bound is an absolute ceiling on the computed max wait. If the max bound itself is a Constant wait its value is fixed and clamping it is contradictory, so RetryStrategy.parse() throws an IllegalArgumentException naming the original spec.","triggerScenarios":"A spec whose max component parses to Wait.Constant while a non-default 'maxmax' absolute ceiling is supplied, e.g. \"500ms;maxmax=1s\" where the max is a constant — the ceiling can never engage.","commonSituations":"Applying global clamp bounds intended for percentile-based max waits to a fixed-wait spec; combining constant bounds and absolute clamps copied from another retry policy configuration.","solutions":["Remove the maxmax ceiling when the max bound is a constant","Use a dynamic max wait (e.g. latency-based) if an absolute ceiling is needed","Leave maxmax unspecified (defaults to Long.MAX_VALUE) to satisfy validation"],"exampleFix":"// before\nRetryStrategy.parse(\"500ms;maxmax=1s\", latencies); // constant max with absolute ceiling\n// after\nRetryStrategy.parse(\"500ms\", latencies); // constant max needs no ceiling","handlingStrategy":"validation","validationCode":"static void validateNoMaxmaxWithConstantMax(String spec, boolean maxIsConstant, boolean hasMaxmaxCeiling) {\n    if (maxIsConstant && hasMaxmaxCeiling)\n        throw new IllegalArgumentException(\"maxmax ceiling meaningless with constant max: \" + spec);\n}","typeGuard":null,"tryCatchPattern":"try {\n    RetryStrategy strategy = RetryStrategy.parse(spec, latencies);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"absolute maximum constant\")) {\n        throw new ConfigurationException(\"Remove the maxmax ceiling for constant max in: \" + spec);\n    }\n    throw e;\n}","preventionTips":["Do not attach a maxmax ceiling when the max wait is a fixed constant","Apply global ceilings only to latency-derived max waits","Add a config lint step that rejects constant-plus-clamp spec combinations"],"tags":["configuration","parsing","conflicting-options"],"backgroundTag":"conflicting-config-options","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}