apache/druid · error · IllegalArgumentException
Rules cannot be null.
Error message
Rules cannot be null.
What it means
SQLMetadataRuleManager.overrideRule() persists an override of the load rules for a datasource. It throws IllegalArgumentException when the newRules list is null; an empty list is allowed (meaning 'no rules for this datasource, fall back to cluster defaults') but null is not a valid rule set.
Solutions
- Pass an empty list instead of null when you intend to clear datasource-specific rules.
- Fix the API client so the request body always includes a rules array.
- Add a null check on the rules list in the calling code before invoking overrideRule.
Example fix
// before ruleManager.overrideRule(dataSource, newRules, auditInfo); // newRules may be null // after ruleManager.overrideRule(dataSource, newRules == null ? Collections.emptyList() : newRules, auditInfo);
Defensive patterns
Strategy: type-guard
Validate before calling
if (rules == null) rules = Collections.emptyList();
Type guard
List<Rule> safeRules(List<Rule> rules) { return rules == null ? Collections.emptyList() : rules; } Try / catch
try {
ruleManager.overrideRule(dataSource, rules, auditInfo);
} catch (IllegalArgumentException e) {
log.error(e, "Rule override rejected: %s", e.getMessage());
} Prevention
- Always serialize rules as an array (possibly empty) in API payloads
- Deserialize request bodies with null-tolerant defaults
- Document that empty list clears overrides, null is invalid
When it happens
Trigger: POSTing to the coordinator rules endpoint with a null 'rules' field; programmatic calls to overrideRule(dataSource, null, auditInfo); deserialization of a request body that omits the rules array.
Common situations: Automation scripts building rule payloads conditionally and omitting the rules key; API clients sending JSON without the rules property; migration tooling between rule APIs.
Related errors
- Cluster-level rules cannot be empty.
- Cannot find any supervisor with id
- Cannot find any task with id
- datasource name cannot be null
- datasource[ ] not found
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/a247dc1ccab1b0aa.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/main/java/org/apache/druid/metadata/SQLMetadataRuleManager.java:314
log.makeAlert(e, "Exception while polling for rules").emit();
failStartTimeMs = 0;
} else {
log.error(e, "Exception while polling for rules");
}
}
}
@Override
public RetentionRulesSnapshot getRulesSnapshot()
{
return rulesSnapshot.get();
}
@Override
public boolean overrideRule(final String dataSource, final List<Rule> newRules, final AuditInfo auditInfo)
{
if (newRules == null) {
throw new IAE("Rules cannot be null.");
} else if (newRules.isEmpty() && config.getDefaultRule().equals(dataSource)) {
throw new IAE("Cluster-level rules cannot be empty.");
}
final String ruleString;
try {
ruleString = jsonMapper.writeValueAsString(newRules);
// uses getAllRules over getOverrideRules to allow proper audit trail when setting explicit [] override rules for
// a datasource with no existing overrides.
if (ruleString.equals(jsonMapper.writeValueAsString(rulesSnapshot.get().getAllRules().get(dataSource)))) {
log.info("Retention rules unchanged for datasource[%s] with rules[%s]", dataSource, ruleString);
return true;
}
log.info("Updating datasource[%s] with rules[%s] as per [%s]", dataSource, ruleString, auditInfo);
}
catch (JsonProcessingException e) {
log.error(e, "Unable to write rules as string for datasource[%s]", dataSource);
return false;View on GitHub (pinned to 9b90983fd2)