apache/cassandra · warning
Compaction strategy does not have a static validateOptions…
Error message
Compaction strategy {} does not have a static validateOptions method. Validation ignored What it means
CompactionParams.validate uses reflection to invoke a compaction strategy class's static validateOptions(Map<String,String>) method to check compaction options. If that method does not exist on the class, validation is skipped and this warning is logged instead of failing the schema change.
Solutions
- Implement a public static Map<String,Object> validateOptions(Map<String,Object> options) method (or Map<String,String>) on the compaction strategy class
- Verify the fully-qualified compaction class name in the compaction options is correct
- Use a built-in strategy (SizeTieredCompactionStrategy, LeveledCompactionStrategy, TimeWindowCompactionStrategy, UnifiedCompactionStrategy) which supports validateOptions
Example fix
// before
public class MyStrategy { /* no validateOptions */ }
// after
public class MyStrategy {
public static Map<String,Object> validateOptions(Map<String,Object> options) {
options.remove(SomeCompactionStrategyOptions.EXTENSION_THRESHOLD.key());
return options;
}
} Defensive patterns
Strategy: validation
Validate before calling
// validate options before attaching a custom strategy
Map<String,Object> accepted = klass.getMethod("validateOptions", Map.class) != null
? (Map<String,Object>) klass.getMethod("validateOptions", Map.class).invoke(null, options)
: options;
if (!accepted.isEmpty()) throw new ConfigurationException("Unknown options: " + accepted.keySet()); Type guard
boolean hasValidateOptions(Class<?> klass) {
try { klass.getMethod("validateOptions", Map.class); return true; }
catch (NoSuchMethodException e) { return false; }
} Try / catch
try { CompactionParams.validate(...); }
catch (ConfigurationException e) { throw new InvalidRequestException("Bad compaction options: " + e.getMessage()); } Prevention
- Implement static validateOptions in every custom compaction strategy
- Prefer built-in compaction strategies when possible
- Double-check fully-qualified class names in compaction options
- Test custom strategies against options validation before deploying
When it happens
Trigger: Setting a compaction strategy (e.g. via setCompactionParameters in a CREATE/ALTER TABLE or CQL options) whose class lacks a static validateOptions method (often a custom third-party strategy).
Common situations: Custom or third-party compaction strategies not following the ICompactionStrategy API contract; typos in the class name resolving to the wrong class; older strategies predating validateOptions.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Cannot access method validateOptions in
- Cannot add new field
- cannot be used in comparisons, so cannot be used as a…
- Cannot set concurrent_validations greater than…
- Cannot set to empty string
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/368d3de3498bc7c5.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/schema/CompactionParams.java:207
{
return tombstoneOption;
}
public void validate()
{
try
{
Map<?, ?> unknownOptions = (Map) klass.getMethod("validateOptions", Map.class).invoke(null, options);
if (!unknownOptions.isEmpty())
{
throw new ConfigurationException(format("Properties specified %s are not understood by %s",
unknownOptions.keySet(),
klass.getSimpleName()));
}
}
catch (NoSuchMethodException e)
{
logger.warn("Compaction strategy {} does not have a static validateOptions method. Validation ignored",
klass.getName());
}
catch (InvocationTargetException e)
{
if (e.getTargetException() instanceof ConfigurationException)
throw (ConfigurationException) e.getTargetException();
Throwable cause = e.getCause() == null
? e
: e.getCause();
throw new ConfigurationException(format("%s.validateOptions() threw an error: %s %s",
klass.getName(),
cause.getClass().getName(),
cause.getMessage()),
e);
}
catch (IllegalAccessException e)View on GitHub (pinned to 88fd0f6a0e)