apache/dubbo · error · IllegalStateException

route rule can not be empty.

Error message

route rule can not be empty.

What it means

Thrown by ScriptStateRouter.getRule() when the script router's 'rule' URL parameter is empty. The script router evaluates a scripting-language rule to filter invokers; enabling/configuring it without a rule body is invalid. Thrown at router construction time.

Source

Thrown at dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/script/ScriptStateRouter.java:115

            function = compilable.compile(rule);
        } catch (ScriptException e) {
            logger.error(
                    CLUSTER_SCRIPT_EXCEPTION,
                    "script route rule invalid",
                    "",
                    "script route error, rule has been ignored. rule: " + rule + ", url: "
                            + RpcContext.getServiceContext().getUrl(),
                    e);
        }
    }

    /**
     * get rule from url parameters.
     */
    private String getRule(URL url) {
        String vRule = url.getParameterAndDecoded(RULE_KEY);
        if (StringUtils.isEmpty(vRule)) {
            throw new IllegalStateException("route rule can not be empty.");
        }
        return vRule;
    }

    /**
     * create ScriptEngine instance by type from url parameters, then cache it
     */
    private ScriptEngine getEngine(URL url) {
        String type = url.getParameter(TYPE_KEY, DEFAULT_SCRIPT_TYPE_KEY);

        return ConcurrentHashMapUtils.computeIfAbsent(ENGINES, type, t -> {
            ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName(type);
            if (scriptEngine == null) {
                throw new IllegalStateException("unsupported route engine type: " + type);
            }
            return scriptEngine;
        });
    }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Provide a non-empty script rule, e.g. rule: 'function invoke(invokers, invocation) { return invokers; }' for the javascript engine.
  2. If you do not need script routing, remove the script router URL or disable it.
  3. Ensure the rule value survives URL-encoding when stored in the registry.

Example fix

# before (broken): script router with no rule
script://0.0.0.0/...?type=javascript

# after
script://0.0.0.0/...?type=javascript&rule=function%20invoke(invokers%2Cinvocation)%7B%20return%20invokers%3B%20%7D
Defensive patterns

Strategy: validation

Validate before calling

// Validate script router rule before constructing
String rule = url.getParameterAndDecoded(RULE_KEY);
if (StringUtils.isEmpty(rule)) {
    throw new IllegalArgumentException(
        "Script router requires a non-empty 'rule' parameter; provide a script or remove the router.");
}
return new ScriptStateRouter<>(url);

Try / catch

try {
    new ScriptStateRouter<>(url);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("route rule can not be empty")) {
        log.error("Script router has no rule; skipping it");
        // omit this router from the chain
    } else throw e;
}

Prevention

When it happens

Trigger: Configuring the script state router (SPI 'script') with a router URL whose 'rule' parameter is missing/empty. getRule(url) reads url.getParameterAndDecoded(RULE_KEY) and rejects blank values.

Common situations: Publishing a script routing rule that omits the script body; URL-encoding problems stripping the rule; copying a router URL template and forgetting to fill in the rule.

Related errors


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