openimsdk/open-im-server · error
topic %s groupID not found
Error message
topic %s groupID not found
What it means
GetTopicConsumer resolves a logical topic name to its real Kafka topic and an associated consumer group ID via two internal maps. This error is thrown when the topic exists in logicalTopic but has no entry in topicGroupID, meaning the builder registered the topic mapping without ever recording a consumer group for it. It signals an inconsistent internal registration state rather than a Kafka-side problem.
Source
Thrown at pkg/mqbuild/builder.go:170
topicGroupID map[string]string
}
func (x *kafkaBuilder) GetTopicProducer(ctx context.Context, topic string) (mq.Producer, error) {
realTopic, ok := x.logicalTopic[topic]
if !ok {
return nil, fmt.Errorf("topic %s not found", topic)
}
return kafka.NewKafkaProducerV2(x.config, x.addr, realTopic)
}
func (x *kafkaBuilder) GetTopicConsumer(ctx context.Context, topic string) (mq.Consumer, error) {
realTopic, ok := x.logicalTopic[topic]
if !ok {
return nil, fmt.Errorf("topic %s not found", topic)
}
groupID, ok := x.topicGroupID[realTopic]
if !ok {
return nil, fmt.Errorf("topic %s groupID not found", realTopic)
}
return kafka.NewMConsumerGroupV2(ctx, x.config, groupID, []string{realTopic}, true)
}
View on GitHub (pinned to 175a7bb067)
Solutions
- Check how the builder populates topicGroupID and ensure the registration path for this topic also sets its consumer group ID before GetTopicConsumer is called.
- Verify your configuration includes a consumer group for every topic registered; fix or add the missing group entry.
- Log both maps (logicalTopic, topicGroupID) at startup and diff them to find the topic missing a group.
- As a defensive measure in your own code, validate the topic/group pair against your config before calling GetTopicConsumer.
- If the group is genuinely optional, change the builder to derive a default groupID (e.g. topic + "-group") instead of erroring.
Example fix
// before (builder init)
builder.RegisterTopic("chat")
// group registration forgotten
// after
builder.RegisterTopic("chat")
builder.SetGroupID("chat", "chat-consumer-group") // populates topicGroupID[realTopic] Defensive patterns
Strategy: validation
Validate before calling
func topicReady(b *mqbuild.Builder, topic string) bool {
real, ok := b.LogicalTopic(topic) // or reflect/inspect your registration API
return ok && b.HasGroupID(real)
}
if !topicReady(builder, "chat") {
return fmt.Errorf("topic %q has no consumer group configured", "chat")
}
_, err := builder.GetTopicConsumer(ctx, "chat") Type guard
func hasConsumerGroup(realTopic string, groups map[string]string) bool {
_, ok := groups[realTopic]
return ok
} Try / catch
cons, err := builder.GetTopicConsumer(ctx, topic)
if err != nil {
if strings.Contains(err.Error(), "groupID not found") {
// fall back: re-register group or surface config error
return fmt.Errorf("misconfigured topic %s: %w", topic, err)
}
return err
} Prevention
- Register topic and consumer group in a single builder method so they can never diverge.
- Validate at startup that every entry in logicalTopic has a matching topicGroupID entry and fail fast.
- Keep topic/group definitions in one config section and generate both maps from it.
- Add a unit test that iterates all registered topics and calls GetTopicConsumer.
When it happens
Trigger: Calling GetTopicConsumer(ctx, topic) for a topic that was added to logicalTopic (e.g. via a builder registration step) but whose group ID was never set in topicGroupID — typically when topic registration and group registration are done in separate calls and only the first ran, or the group ID was cleared/never configured for that topic.
Common situations: Partial configuration: a topic is declared in config but the consumer-group section for it is missing or misnamed; a builder was constructed programmatically where RegisterTopic was called without the corresponding group registration; refactor or version change where group IDs moved to a new map and legacy init code no longer populates it.
Related errors
- config field %s %s not found
- no command to run
- standalone api port is 0
- invalid object enable: %s
- failed to create in-cluster config: %v
AI-assisted analysis of openimsdk/open-im-server@175a7bb067 (2026-09-04).
Data as JSON: /api/errors/b6c7a2abef911a9e.
Report an issue: GitHub.