apache/dubbo · error · IllegalArgumentException

Illegal route rule!

Error message

Illegal route rule!

What it means

Thrown by ConditionStateRouter.init() when the route rule is null or blank. The condition state router is driven by a 'rule' URL parameter (URL-encoded, e.g. 'consumer.region=-east => provider.region=east'); enabling the router without that rule is invalid.

Source

Thrown at dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/condition/ConditionStateRouter.java:109

        }
    }

    public ConditionStateRouter(URL url) {
        super(url);
        this.setUrl(url);
        this.setForce(url.getParameter(FORCE_KEY, false));
        matcherFactories =
                moduleModel.getExtensionLoader(ConditionMatcherFactory.class).getActivateExtensions();
        this.enabled = url.getParameter(ENABLED_KEY, true);
        if (enabled) {
            init(url.getParameterAndDecoded(RULE_KEY));
        }
    }

    public void init(String rule) {
        try {
            if (rule == null || rule.trim().length() == 0) {
                throw new IllegalArgumentException("Illegal route rule!");
            }
            rule = rule.replace("consumer.", "").replace("provider.", "");
            int i = rule.indexOf("=>");
            String whenRule = i < 0 ? null : rule.substring(0, i).trim();
            String thenRule = i < 0 ? rule.trim() : rule.substring(i + 2).trim();
            Map<String, ConditionMatcher> when =
                    StringUtils.isBlank(whenRule) || "true".equals(whenRule) ? new HashMap<>() : parseRule(whenRule);
            Map<String, ConditionMatcher> then =
                    StringUtils.isBlank(thenRule) || "false".equals(thenRule) ? null : parseRule(thenRule);
            // NOTE: It should be determined on the business level whether the `When condition` can be empty or not.
            this.whenCondition = when;
            this.thenCondition = then;
        } catch (ParseException e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    private Map<String, ConditionMatcher> parseRule(String rule) throws ParseException {

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Provide a non-empty condition rule, e.g. rule: 'consumer.host = 10.20.* => provider.host = 10.20.*'.
  2. If you do not need condition routing, set enabled=false or remove the router URL.
  3. Verify the rule survives URL-encoding/decoding (use the encoded form in override:// URLs).

Example fix

# before (broken): condition router enabled, no rule
override://0.0.0.0/...?router=condition&condition.router.enabled=true

# after (URL-encode the rule)
override://0.0.0.0/...?router=condition&condition.router.enabled=true&rule=consumer.region%3D east %3D%3E provider.region%3D east
Defensive patterns

Strategy: validation

Validate before calling

// Validate condition router rule before constructing
String rule = url.getParameterAndDecoded(RULE_KEY);
boolean enabled = url.getParameter(ENABLED_KEY, true);
if (enabled && (rule == null || rule.trim().isEmpty())) {
    throw new IllegalArgumentException(
        "Condition router enabled but 'rule' is empty; provide a rule or disable the router.");
}
return new ConditionStateRouter<>(url);

Try / catch

try {
    new ConditionStateRouter<>(url);
} catch (IllegalArgumentException | IllegalStateException e) {
    // bad condition rule; fall back to no condition routing
    log.error("Condition router disabled due to bad rule: " + e.getMessage());
    url = url.addParameter(ENABLED_KEY, false);
}

Prevention

When it happens

Trigger: Configuring the condition state router (SPI 'condition') with enabled=true (the default) but the 'rule' parameter is missing or empty in the router URL. init(url.getParameterAndDecoded(RULE_KEY)) receives null/blank.

Common situations: Publishing a condition routing rule that omits the rule body; URL-encoding the rule incorrectly so it decodes to empty; a registry/notification glitch delivering a rule URL without its rule param.

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/82c2c1980b0aa99c. Report an issue: GitHub.