{"record":{"id":"a29e60c1546964a6","repo":"aeron-io/aeron","slug":"service-count-of-range-0-max-service-count-servicecount","errorCode":null,"errorMessage":"service count of range [0, MAX_SERVICE_COUNT]: serviceCount","messagePattern":"service count of range \\[0, MAX_SERVICE_COUNT\\]: serviceCount","errorType":"validation","errorClass":"ClusterException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModule.java","lineNumber":1736,"sourceCode":"            }\n        }\n\n        /**\n         * Conclude configuration by setting up defaults when specifics are not provided.\n         */\n        @SuppressWarnings(\"MethodLength\")\n        public void conclude()\n        {\n            if ((boolean)IS_CONCLUDED_VH.getAndSet(this, true))\n            {\n                throw new ConcurrentConcludeException();\n            }\n\n            validateLogChannel();\n\n            if (serviceCount < 0 || serviceCount > MAX_SERVICE_COUNT)\n            {\n                throw new ClusterException(\"service count of range [0, \" + MAX_SERVICE_COUNT + \"]: \" + serviceCount);\n            }\n\n            if (null == clusterDir)\n            {\n                clusterDir = new File(clusterDirectoryName);\n            }\n\n            if (null == markFileDir)\n            {\n                final String dir = ClusteredServiceContainer.Configuration.markFileDir();\n                markFileDir = Strings.isEmpty(dir) ? clusterDir : new File(dir);\n            }\n\n            try\n            {\n                clusterDir = clusterDir.getCanonicalFile();\n                clusterDirectoryName = clusterDir.getAbsolutePath();\n                markFileDir = markFileDir.getCanonicalFile();","sourceCodeStart":1718,"sourceCodeEnd":1754,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModule.java#L1718-L1754","documentation":"During conclude(), the configured serviceCount is validated against the range [0, MAX_SERVICE_COUNT] (max 20 in Aeron Cluster). A negative or over-limit service count means the cluster cannot allocate per-service state, so conclude() throws a ClusterException immediately.","triggerScenarios":"Setting ConsensusModule.Context.serviceCount() to a negative value or a value greater than MAX_SERVICE_COUNT (20) before conclude().","commonSituations":"Misreading serviceCount semantics (services per cluster vs. total cluster instances); computing the count dynamically and accidentally passing -1 or 0-padded garbage; copying config from a scaled deployment with more than 20 services.","solutions":["Set serviceCount() to the actual number of clustered services, between 0 and 20","Check for arithmetic/parse bugs producing a negative count","Split the workload across multiple clusters if more than 20 services are needed"],"exampleFix":"// before\nctx.serviceCount(-1); // or 25\n// after\nctx.serviceCount(3); // number of ClusteredServices in this node","handlingStrategy":"validation","validationCode":"int serviceCount = /* configured */;\nif (serviceCount < 0 || serviceCount > ConsensusModule.Configuration.MAX_SERVICE_COUNT) {\n    throw new IllegalArgumentException(\"serviceCount out of range: \" + serviceCount);\n}","typeGuard":null,"tryCatchPattern":"try { ctx.conclude(); } catch (ClusterException e) { log.error(\"bad serviceCount\", e); }","preventionTips":["Derive serviceCount from the number of registered ClusteredService factories","Clamp/validate user-supplied counts at config load time","Remember the inclusive upper bound is MAX_SERVICE_COUNT (20)"],"tags":["configuration","validation"],"backgroundTag":"value-out-of-range","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}