{"record":{"id":"6910eec855750d4b","repo":"apache/dubbo","slug":"illegal-affinity-rule","errorCode":null,"errorMessage":"Illegal affinity rule!","messagePattern":"Illegal affinity rule!","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/affinity/AffinityStateRouter.java","lineNumber":98,"sourceCode":"        }\n    }\n\n    public AffinityStateRouter(URL url, String affinityKey, Double ratio, boolean enabled) {\n        super(url);\n        this.enabled = enabled;\n        this.affinityKey = affinityKey;\n        this.ratio = ratio;\n        matcherFactories =\n                moduleModel.getExtensionLoader(ConditionMatcherFactory.class).getActivateExtensions();\n        if (this.enabled) {\n            this.init(affinityKey);\n        }\n    }\n\n    public void init(String rule) {\n        try {\n            if (rule == null || rule.trim().isEmpty()) {\n                throw new IllegalArgumentException(\"Illegal affinity rule!\");\n            }\n            this.matchMatcher = parseRule(affinityKey);\n        } catch (ParseException e) {\n            throw new IllegalStateException(e.getMessage(), e);\n        }\n    }\n\n    private ConditionMatcher parseRule(String rule) throws ParseException {\n        ConditionMatcher matcher = getMatcher(rule);\n        // Multiple values\n        Set<String> values = matcher.getMatches();\n        values.add(getUrl().getParameter(rule));\n        return matcher;\n    }\n\n    @Override\n    protected BitList<Invoker<T>> doRoute(\n            BitList<Invoker<T>> invokers,","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/affinity/AffinityStateRouter.java#L80-L116","documentation":"Thrown by AffinityStateRouter.init() when the affinity rule (affinityKey) is null or blank. The affinity state router routes to providers matching an affinity key; enabling it without supplying an affinity key is a configuration error. Note the constructor also throws IllegalStateException wrapping a ParseException if rule parsing fails.","triggerScenarios":"Configuring the affinity router (SPI 'affinity') with enabled=true but no 'affinityKey' parameter (it defaults to empty string), or constructing AffinityStateRouter with a null/blank affinityKey while enabled.","commonSituations":"Enabling the affinity router via URL/registry rule but omitting the affinityKey field; a malformed mesh/affinity rule where the key was not substituted; misconfiguring the SPI extension URL.","solutions":["Provide a non-empty affinityKey in the affinity router configuration URL (the parameter name is affinityKey / the AFFINITY_KEY constant).","If you do not need affinity routing, disable the router (enabled=false) or remove it from the chain.","Double-check the rule string is not trimmed to empty; the check is on rule.trim().isEmpty()."],"exampleFix":"# before (broken): affinity enabled with no key\noverride://0.0.0.0/...?router=affinity&affinity.router.enabled=true\n\n# after\noverride://0.0.0.0/...?router=affinity&affinity.router.enabled=true&affinityKey=region","handlingStrategy":"validation","validationCode":"// Validate affinity router config before constructing\nString key = url.getParameter(AFFINITY_KEY, \"\");\nboolean enabled = url.getParameter(ENABLED_KEY, true);\nif (enabled && (key == null || key.trim().isEmpty())) {\n    throw new IllegalArgumentException(\n        \"Affinity router enabled but 'affinityKey' is missing; set it or disable the router.\");\n}\nreturn new AffinityStateRouter<>(url);","typeGuard":null,"tryCatchPattern":"try {\n    new AffinityStateRouter<>(url);\n} catch (IllegalArgumentException | IllegalStateException e) {\n    // router misconfiguration; disable affinity and continue without it, or fail config validation\n    log.error(\"Affinity router disabled due to bad config: \" + e.getMessage());\n    url = url.addParameter(ENABLED_KEY, false);\n}","preventionTips":["Always supply a non-empty affinityKey when enabling the affinity router.","Disable (enabled=false) the router instead of leaving it half-configured.","Validate the rule string in config linting before publishing."],"tags":["router","affinity","config","validation"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}