{"record":{"id":"619301850162b1ab","repo":"apache/rocketmq","slug":"lite-subscription-quota-exceeded","errorCode":null,"errorMessage":"lite subscription quota exceeded ","messagePattern":"lite subscription quota exceeded ","errorType":"exception","errorClass":"LiteQuotaException","httpStatus":null,"severity":"error","filePath":"broker/src/main/java/org/apache/rocketmq/broker/lite/LiteSubscriptionRegistryImpl.java","lineNumber":87,"sourceCode":"        this.liteLifecycleManager = liteLifecycleManager;\n    }\n\n    // Number of active liteTopic references.\n    // [(client1, liteTopic1), (client2, liteTopic1)] counts as two active references.\n    protected final AtomicInteger activeNum = new AtomicInteger(0);\n\n    @Override\n    public void updateClientChannel(String clientId, Channel channel) {\n        clientChannels.put(clientId, channel);\n    }\n\n    @Override\n    public void addPartialSubscription(String clientId, String group, String topic, Set<String> lmqNameSet,\n        OffsetOption offsetOption) {\n        long maxCount = brokerController.getBrokerConfig().getMaxLiteSubscriptionCount();\n        if (getActiveSubscriptionNum() >= maxCount) {\n            // No need to check existence, if reach here, it must be new.\n            throw new LiteQuotaException(\"lite subscription quota exceeded \" + maxCount);\n        }\n        if (LiteMetadataUtil.isWildcardGroup(group, brokerController)) {\n            throw new IllegalStateException(\"subscribe lite operation is not supported for this group\");\n        }\n\n        LiteSubscription thisSub = getOrCreateLiteSubscription(clientId, group, topic);\n        // Utilize existing string object\n        final ClientGroup clientGroup = new ClientGroup(clientId, thisSub.getGroup());\n        for (String lmqName : lmqNameSet) {\n            if (!liteLifecycleManager.isSubscriptionActive(topic, lmqName)) {\n                continue;\n            }\n            thisSub.addLiteTopic(lmqName);\n            // First remove the old subscription\n            if (LiteMetadataUtil.isSubLiteExclusive(group, brokerController)) {\n                excludeClientByLmqName(clientId, group, lmqName);\n                // Boundary case: this client may have a stale tombstone from a previous eviction.\n                // Since it is now actively re-claiming the lmqName, clear its own tombstone so","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/broker/src/main/java/org/apache/rocketmq/broker/lite/LiteSubscriptionRegistryImpl.java#L69-L105","documentation":"LiteSubscriptionRegistryImpl.addPartialSubscription() throws LiteQuotaException when the number of active lite (LMQ) subscriptions has reached brokerConfig.maxLiteSubscriptionCount. This is a self-protection cap on lightweight-partial-consumption state, checked before the new subscription is registered; the message suffix carries the configured limit.","triggerScenarios":"A lite/LMQ client issuing a subscribe (addPartialSubscription) once getActiveSubscriptionNum() >= maxLiteSubscriptionCount; typically a churn of clients subscribing to many distinct LMQ topics pushes the active count over the cap.","commonSituations":"Lighweight-consumer deployments (lite pull consumers on LMQ topics) scaling past the default quota; subscription leaks — clients reconnecting without releasing old subscriptions keeping the active count high; a deliberately small maxLiteSubscriptionCount in test configs.","solutions":["Raise maxLiteSubscriptionCount in broker.conf to a value above your expected peak active lite subscription count and restart/reload the broker","Audit active lite subscriptions and expire idle ones so leaked subscriptions stop consuming quota","Ensure lite clients unsubscribe/clean up on disconnect so counts decay"],"exampleFix":"# before (broker.conf)\n# maxLiteSubscriptionCount left at default (too small for the workload)\n\n# after (broker.conf)\nmaxLiteSubscriptionCount=100000","handlingStrategy":"validation","validationCode":"// client/broker-side guard before subscribing lite\nif (registry.getActiveSubscriptionNum() >= brokerConfig.getMaxLiteSubscriptionCount()) {\n    throw new IllegalStateException(\"raise maxLiteSubscriptionCount or expire idle subscriptions\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    registry.addPartialSubscription(clientId, group, topic, lmqSet, option);\n} catch (LiteQuotaException e) {\n    // back off, alert operator, or shed load; do not retry-loop immediately\n}","preventionTips":["Size maxLiteSubscriptionCount from peak concurrent lite clients x topics and add headroom","Ensure lite clients unsubscribe on disconnect so quota is reclaimed","Alert on activeSubscriptionNum approaching the cap"],"tags":["broker","lite","lmq","quota","subscription","config","rocketmq"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}