{"record":{"id":"a80fd9b58a9c90c9","repo":"apache/cassandra","slug":"invalid-to-specify-an-absolute-minimum-constant-wh","errorCode":null,"errorMessage":"Invalid to specify an absolute minimum constant when the min bound is itself a constant: '${original}'","messagePattern":"Invalid to specify an absolute minimum constant when the min bound is itself a constant: '(.+?)'","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/RetryStrategy.java","lineNumber":315,"sourceCode":"                end = next;\n            }\n            if (end != spec.length())\n                spec = spec.substring(0, end);\n        }\n\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;","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/RetryStrategy.java#L297-L333","documentation":"The spec grammar allows an absolute floor (minmin) on the computed min wait, but if the min bound is a Constant wait there is nothing to vary below it, so a non-zero absolute minimum is contradictory. RetryStrategy.parse() throws an IllegalArgumentException naming the original spec.","triggerScenarios":"A spec where the min component parses to Wait.Constant and the 'minmin' absolute lower floor is non-zero, e.g. a constant min bound combined with a ';floor' clamp in the spec grammar.","commonSituations":"Combining a constant wait with clamp syntax intended only for dynamic/percentile-based waits; copy-pasting bounds syntax from a latency-based spec onto a constant one.","solutions":["Remove the absolute minimum (minmin) clause when the min bound is a constant","Change the min bound from a constant to a dynamic wait (e.g. percentile-based) if the floor is required","Leave minmin at its default of 0 so the check passes"],"exampleFix":"// before\nRetryStrategy.parse(\"500ms;100ms..1s\", latencies); // constant min with absolute floor\n// after\nRetryStrategy.parse(\"500ms..1s\", latencies); // use a ranged min instead of constant+floor","handlingStrategy":"validation","validationCode":"// ensure an absolute minimum (minmin) is only used with non-constant min bounds\nstatic void validateNoMinminWithConstantMin(String spec, boolean minIsConstant, boolean hasMinminFloor) {\n    if (minIsConstant && hasMinminFloor)\n        throw new IllegalArgumentException(\"minmin floor meaningless with constant min: \" + spec);\n}","typeGuard":null,"tryCatchPattern":"try {\n    RetryStrategy strategy = RetryStrategy.parse(spec, latencies);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"absolute minimum constant\")) {\n        throw new ConfigurationException(\"Remove the absolute-min clamp for constant min in: \" + spec);\n    }\n    throw e;\n}","preventionTips":["Reserve absolute clamp bounds for dynamic (latency/percentile) waits","Do not mix constant bounds with minmax clamp syntax in generated specs","Review spec templates to emit clamps only when the bound type warrants them"],"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"}