{"record":{"id":"9e8d045e130ddaf2","repo":"alibaba/spring-cloud-alibaba","slug":"group-must-be-configured-for-dlq-destination-getna","errorCode":null,"errorMessage":"group must be configured for DLQ{destination.getName()}","messagePattern":"group must be configured for DLQ(.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java","lineNumber":126,"sourceCode":"\tprotected MessageHandler createProducerMessageHandler(ProducerDestination destination,\n\t\t\tExtendedProducerProperties<RocketMQProducerProperties> producerProperties,\n\t\t\tMessageChannel errorChannel) throws Exception {\n\t\tthrow new UnsupportedOperationException(\n\t\t\t\t\"The abstract binder should not call this method\");\n\t}\n\n\t@Override\n\tprotected MessageProducer createConsumerEndpoint(ConsumerDestination destination,\n\t\t\tString group,\n\t\t\tExtendedConsumerProperties<RocketMQConsumerProperties> extendedConsumerProperties)\n\t\t\tthrows Exception {\n\t\tboolean anonymous = !StringUtils.hasLength(group);\n\t\t/***\n\t\t * \tWhen using DLQ, at least the group property must be provided for proper naming of the DLQ destination\n\t\t *  According to https://docs.spring.io/spring-cloud-stream/docs/3.2.1/reference/html/spring-cloud-stream.html#spring-cloud-stream-reference\n\t\t */\n\t\tif (anonymous && NamespaceUtil.isDLQTopic(destination.getName())) {\n\t\t\tthrow new RuntimeException(\n\t\t\t\t\t\"group must be configured for DLQ\" + destination.getName());\n\t\t}\n\t\tgroup = anonymous ? RocketMQUtils.anonymousGroup(destination.getName()) : group;\n\n\t\tRocketMQUtils.mergeRocketMQProperties(binderConfigurationProperties,\n\t\t\t\textendedConsumerProperties.getExtension());\n\t\textendedConsumerProperties.getExtension().setGroup(group);\n\n\t\tRocketMQInboundChannelAdapter inboundChannelAdapter = new RocketMQInboundChannelAdapter(\n\t\t\t\tdestination.getName(), extendedConsumerProperties);\n\t\tinboundChannelAdapter.setBeanFactory(this.getApplicationContext().getBeanFactory());\n\t\tErrorInfrastructure errorInfrastructure = registerErrorInfrastructure(destination,\n\t\t\t\tgroup, extendedConsumerProperties);\n\t\tif (extendedConsumerProperties.getMaxAttempts() > 1) {\n\t\t\tinboundChannelAdapter\n\t\t\t\t\t.setRetryTemplate(buildRetryTemplate(extendedConsumerProperties));\n\t\t\tinboundChannelAdapter.setRecoveryCallback(errorInfrastructure.getRecoverer());\n\t\t}","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/alibaba/spring-cloud-alibaba/blob/115d5901102009492e05d5ec18c3f79cad4077d0/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java#L108-L144","documentation":"Thrown in RocketMQMessageChannelBinder.createConsumerEndpoint (push consumer) when the consumer is anonymous (no `group`) but the destination name is recognized as a DLQ topic. Spring Cloud Stream requires a concrete group so the DLQ destination can be named deterministically. RocketMQ marks DLQ topics with the `%DLQ%` prefix (detected via NamespaceUtil.isDLQTopic).","triggerScenarios":"Consuming from a `%DLQ%`-prefixed destination with `spring.cloud.stream.bindings.<input>.group` unset/empty (anonymous consumer).","commonSituations":"Pointing an input binding at a DLQ topic for retry/replay but forgetting to set `group`; a DLQ name auto-built without a group; migrating a Kafka-style anonymous consumer to a RocketMQ DLQ.","solutions":["Set `spring.cloud.stream.bindings.<input>.group=<stable-group>` so the consumer is not anonymous.","If you did not intend DLQ handling, point the binding destination back at the original topic.","Verify the destination name does not carry the `%DLQ%` prefix unintentionally."],"exampleFix":"// before - anonymous consumer on a DLQ topic\nspring:\n  cloud:\n    stream:\n      bindings:\n        dlqInput:\n          destination: '%DLQ%myGroup'\n          # group missing  -> [121]\n# after\nspring:\n  cloud:\n    stream:\n      bindings:\n        dlqInput:\n          destination: '%DLQ%myGroup'\n          group: my-dlq-consumer-group","handlingStrategy":"validation","validationCode":"// Reject anonymous DLQ subscriptions before the binder builds the endpoint.\nString group = extendedConsumerProperties.getGroup();\nboolean anonymous = !StringUtils.hasLength(group);\nif (anonymous && org.apache.rocketmq.common.namespace.NamespaceUtil\n        .isDLQTopic(destination.getName())) {\n    throw new IllegalStateException(\"Set spring.cloud.stream.bindings.<input>.group for DLQ consumer\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set an explicit `group` for any RocketMQ input, especially DLQ ones.","Treat a `%DLQ%` destination as a signal to audit group config.","Anonymous (groupless) RocketMQ consumers should never target DLQ topics."],"tags":["rocketmq","spring-cloud-stream","dlq","consumer","config"],"backgroundTag":null,"analyzedSha":"115d5901102009492e05d5ec18c3f79cad4077d0","analyzedAt":"2026-08-14T04:47:13.900Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}