apache/cassandra · error · ConfigurationException
Invalid value for option ' ': MIN()/MAX() arguments should…
Error message
Invalid value %s for option '%s': MIN()/MAX() arguments should be of different types, but both are of type %s
What it means
Thrown by HybridSpeculativeRetryPolicy.fromString when parsing a MIN()/MAX() speculative_retry value whose two arguments are the same kind (e.g. MIN(50ms, 60ms) — both fixed, or MIN(50p, 99p) — both percentile). MIN/MAX hybrids require one fixed and one percentile argument so the policy can pick between a time bound and a percentile bound.
Solutions
- Change the MIN()/MAX() arguments so one is a fixed time (e.g. 50ms) and the other a percentile (e.g. 99p)
- If only one bound is needed, drop the hybrid entirely and set speculative_retry to the plain value (e.g. '50ms' or '99p')
- Use 'NONE' to disable speculative retries and re-evaluate the intended tuning
Example fix
// before ALTER TABLE ks.tbl WITH speculative_retry = 'MIN(50ms, 95ms)'; // after ALTER TABLE ks.tbl WITH speculative_retry = 'MIN(50ms, 95p)';
Defensive patterns
Strategy: validation
Validate before calling
function isValidSpeculativeRetry(v) {
const m = /^(MIN|MAX)\(([^,]+),([^,]+)\)$/i.exec(v.trim());
if (!m) return false;
const kind = s => /p$|percentile$/i.test(s.trim()) ? 'percentile' : 'fixed';
return kind(m[2]) !== kind(m[3]);
}
if (!isValidSpeculativeRetry('MIN(50ms, 95p)')) throw new Error('MIN/MAX needs one fixed and one percentile arg'); Prevention
- Always pair one 'ms' value with one 'p' value inside MIN()/MAX()
- Use DESCRIBE TABLE to copy known-good speculative_retry syntax
- Validate table options in CI with a CREATE TABLE smoke test against a test keyspace
When it happens
Trigger: Setting speculative_retry to MIN(x,y) or MAX(x,y) via CREATE/ALTER TABLE or TableParams where both x and y parse to the same kind: both milliseconds/fixed values or both percentile values (e.g. 'MIN(10ms, 99p)' is valid but 'MIN(10ms, 20ms)' is not).
Common situations: Copy-pasting speculative_retry settings from old configs or docs; misunderstanding that MIN/MAX compare one time bound and one percentile; typos like 'MIN(50p, 99PERCENTILE)' where both parse as percentiles.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Invalid value for option
- Invalid value for option
- Invalid value for PERCENTILE option ' ': must be between…
- Cannot create table . with transactional mode with…
- could not parse update query
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/4ef8091c1e7df406.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/service/reads/HybridSpeculativeRetryPolicy.java:125
throw new IllegalArgumentException();
String val1 = matcher.group("val1");
String val2 = matcher.group("val2");
SpeculativeRetryPolicy value1, value2;
try
{
value1 = SpeculativeRetryPolicy.fromString(val1);
value2 = SpeculativeRetryPolicy.fromString(val2);
}
catch (ConfigurationException e)
{
throw new ConfigurationException(String.format("Invalid value %s for option '%s'", str, TableParams.Option.SPECULATIVE_RETRY));
}
if (value1.kind() == value2.kind())
{
throw new ConfigurationException(String.format("Invalid value %s for option '%s': MIN()/MAX() arguments " +
"should be of different types, but both are of type %s",
str, TableParams.Option.SPECULATIVE_RETRY, value1.kind()));
}
SpeculativeRetryPolicy policy1 = value1 instanceof PercentileSpeculativeRetryPolicy ? value1 : value2;
SpeculativeRetryPolicy policy2 = value1 instanceof FixedSpeculativeRetryPolicy ? value1 : value2;
Function function = Function.valueOf(toUpperCaseLocalized(matcher.group("fun")));
return new HybridSpeculativeRetryPolicy((PercentileSpeculativeRetryPolicy) policy1, (FixedSpeculativeRetryPolicy) policy2, function);
}
static boolean stringMatches(String str)
{
return PATTERN.matcher(str).matches();
}
}
View on GitHub (pinned to 88fd0f6a0e)