{"record":{"id":"63d4fc1128085d0f","repo":"apereo/cas","slug":"invalid-unique-index-must-be-0-and-256","errorCode":null,"errorMessage":"Invalid unique index: must be >= 0 and < 256","messagePattern":"Invalid unique index: must be >= 0 and < 256","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"webapp/cas-server-webapp-init-tomcat/src/main/java/org/apereo/cas/tomcat/CasTomcatServletWebServerFactory.java","lineNumber":228,"sourceCode":"    @ToString\n    private static final class ClusterMemberDesc {\n        private static final int UNIQUE_ID_LIMIT = 255;\n\n        private static final int UNIQUE_ID_ITERATIONS = 16;\n\n        private final String address;\n\n        private final int port;\n\n        private String uniqueId;\n\n        ClusterMemberDesc(final String spec) {\n            val values = spec.split(\":\", -1);\n            address = values[0];\n            port = Integer.parseInt(values[1]);\n            var index = Integer.parseInt(values[2]);\n            if (index < 0 || index > UNIQUE_ID_LIMIT) {\n                throw new IllegalArgumentException(\"Invalid unique index: must be >= 0 and < 256\");\n            }\n            uniqueId = \"{\";\n            for (var i = 0; i < UNIQUE_ID_ITERATIONS; i++, index++) {\n                if (i != 0) {\n                    uniqueId += ',';\n                }\n                uniqueId += index % (UNIQUE_ID_LIMIT + 1);\n            }\n            uniqueId += '}';\n        }\n    }\n}\n","sourceCodeStart":210,"sourceCodeEnd":241,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/webapp/cas-server-webapp-init-tomcat/src/main/java/org/apereo/cas/tomcat/CasTomcatServletWebServerFactory.java#L210-L241","documentation":"CasTomcatServletWebServerFactory.ClusterMemberDesc parses cluster member specs of the form address:port:index for Tomcat cluster session replication. It throws IllegalArgumentException when the third field (the unique index used to build the member's uniqueId bytes) is negative or exceeds UNIQUE_ID_LIMIT (255).","triggerScenarios":"A cluster membership property value passed to the embedded Tomcat factory (e.g. -Dcas.webserver.cluster.membership=host1:4000:300) contains an index outside 0-255, or the spec has malformed numeric fields.","commonSituations":"Typo when configuring Tomcat cluster membership in a multi-node deployment; copying an index from another node without rebasing; hand-editing env vars in Kubernetes/compose files.","solutions":["Set each member's unique index to a distinct value in the range 0-255 (e.g. 0, 1, 2 ...).","Use the full address:port:index spec format with exactly three colon-separated numeric fields.","Assign indexes deterministically per node (e.g. via per-node env config) so no node exceeds 255 in large fleets."],"exampleFix":"// before\n-Dcas.webserver.cluster.membership=node1:4000:300\n// after\n-Dcas.webserver.cluster.membership=node1:4000:3","handlingStrategy":"validation","validationCode":"// validate the membership spec before startup\ndef spec = 'node1:4000:3'\ndef parts = spec.split(':', -1)\nassert parts.length == 3\nassert parts[2].isInteger() && parts[2].toInteger() in 0..255","typeGuard":"static boolean isValidMemberSpec(String spec) {\n    var parts = spec.split(\":\", -1);\n    if (parts.length != 3) return false;\n    try { int i = Integer.parseInt(parts[2]); return i >= 0 && i < 256; }\n    catch (NumberFormatException e) { return false; }\n}","tryCatchPattern":null,"preventionTips":["Assign per-node indexes via templated config so they stay within 0-255.","Validate cluster membership values in CI/deployment scripts before rollout.","Keep a documented mapping of node -> index per environment."],"tags":["tomcat","cluster","configuration","startup"],"backgroundTag":"value-out-of-range","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}