alibaba/Sentinel · error · IllegalArgumentException

Not a valid RLS rule

Error message

Not a valid RLS rule

What it means

EnvoySentinelRuleConverter.toSentinelFlowRules() converts an EnvoyRlsRule into Sentinel FlowRules; first it validates the rule via EnvoyRlsRuleManager.isValidRule (domain non-empty and descriptors non-empty). Failing validation it throws IllegalArgumentException('Not a valid RLS rule') — the loaded YAML does not contain the required fields.

Source

Thrown at sentinel-cluster/sentinel-cluster-server-envoy-rls/src/main/java/com/alibaba/csp/sentinel/cluster/server/envoy/rls/rule/EnvoySentinelRuleConverter.java:46

 * @author Eric Zhao
 * @since 1.7.0
 */
public final class EnvoySentinelRuleConverter {

    /**
     * Currently we use "|" to separate each key/value entries.
     */
    public static final String SEPARATOR = "|";

    /**
     * Convert the {@link EnvoyRlsRule} to a list of Sentinel flow rules.
     *
     * @param rule a valid Envoy RLS rule
     * @return converted rules
     */
    public static List<FlowRule> toSentinelFlowRules(EnvoyRlsRule rule) {
        if (!EnvoyRlsRuleManager.isValidRule(rule)) {
            throw new IllegalArgumentException("Not a valid RLS rule");
        }
        return rule.getDescriptors().stream()
            .map(e -> toSentinelFlowRule(rule.getDomain(), e))
            .collect(Collectors.toList());
    }

    public static FlowRule toSentinelFlowRule(String domain, EnvoyRlsRule.ResourceDescriptor descriptor) {
        // One descriptor could have only one rule.
        String identifier = generateKey(domain, descriptor);
        long flowId = generateFlowId(identifier);
        return new FlowRule(identifier)
            .setCount(descriptor.getCount())
            .setClusterMode(true)
            .setClusterConfig(new ClusterFlowConfig()
                .setFlowId(flowId)
                .setThresholdType(ClusterRuleConstant.FLOW_THRESHOLD_GLOBAL)
                .setSampleCount(1)
                .setFallbackToLocalWhenFail(false));

View on GitHub (pinned to a3f40ba8e9)

Solutions

  1. Ensure the YAML has a non-empty 'domain' and at least one entry under 'descriptors'
  2. Check indentation so descriptors is a top-level list of the rule
  3. Add a startup validation/lint step for the rule file, or unit-test EnvoySentinelRuleConverter.toSentinelFlowRules on the config
  4. Example minimal rule: domain: foo\ndescriptors:\n - key: userId\n value: '1'\n count: 10

Example fix

# before (invalid)
domain: ""
descriptors: []

# after (valid)
domain: my-service
descriptors:
  - key: userId
    value: "1001"
    tokensPerFill: 10
    fillInterval: 1s
Defensive patterns

Strategy: validation

Validate before calling

EnvoyRlsRule rule = yaml.loadAs(text, EnvoyRlsRule.class);
if (rule == null || StringUtil.isBlank(rule.getDomain())
        || rule.getDescriptors() == null || rule.getDescriptors().isEmpty()) {
    throw new IllegalArgumentException("RLS rule YAML must define domain and at least one descriptor");
}

Prevention

When it happens

Trigger: Feeding an EnvoyRlsRule with null/blank domain or null/empty descriptors list; YAML structurally parseable but missing 'domain:' or 'descriptors:' keys (or descriptors: with no entries).

Common situations: Hand-writing the RLS YAML and omitting the domain; a descriptors block with only comments/empty list; YAML indentation making descriptors parse as part of another key; empty config file.

Related errors


AI-assisted analysis of alibaba/Sentinel@a3f40ba8e9 (2026-08-14). Data as JSON: /api/errors/50d2b880691ab957. Report an issue: GitHub.