t8y2/dbx · error

decode consumer status: %w

Error message

decode consumer status: %w

What it means

decodeConsumerStatus unmarshals the broker's GetConsumerStatus response body into a wrapper struct with a consumerTable field (a workaround for admin-go v1.1.1 decoding the full response as the inner table). This error wraps any json.Unmarshal failure after repairConsumerStatusJSON has attempted to fix non-standard JSON (e.g. object-keyed int64 maps).

Source

Thrown at agents/drivers/rocketmq/consumers.go:372

			for _, queueKey := range sortedKeys(partial[clientID]) {
				merged[clientID][queueKey] = partial[clientID][queueKey]
			}
		}
	}
	if successCount == 0 {
		return nil, fmt.Errorf("query consumer status for group %s on all masters: %w", groupID, lastErr)
	}
	return merged, nil
}

func decodeConsumerStatus(body []byte) (map[string]map[string]int64, error) {
	// RocketMQ wraps assignments in GetConsumerStatusBody; admin-go v1.1.1
	// incorrectly decodes the complete response as the inner table.
	var wrapper struct {
		ConsumerTable map[string]map[string]int64 `json:"consumerTable"`
	}
	if err := json.Unmarshal(repairConsumerStatusJSON(body), &wrapper); err != nil {
		return nil, fmt.Errorf("decode consumer status: %w", err)
	}
	if wrapper.ConsumerTable == nil {
		wrapper.ConsumerTable = make(map[string]map[string]int64)
	}
	return wrapper.ConsumerTable, nil
}

func repairConsumerStatusJSON(body []byte) []byte {
	repaired := repairRocketMQJSON(body)
	result := make([]byte, 0, len(repaired)+64)
	for index := 0; index < len(repaired); {
		mapStart := index + 1
		for mapStart < len(repaired) && isJSONSpace(repaired[mapStart]) {
			mapStart++
		}
		if repaired[index] == ':' && mapStart+1 < len(repaired) &&
			repaired[mapStart] == '{' && repaired[mapStart+1] == '{' {
			if converted, next, ok := convertObjectKeyedInt64Map(repaired, mapStart); ok {

View on GitHub (pinned to c0390bff16)

Solutions

  1. Log the raw response body (hex or string) for the failing broker and identify what non-JSON content was returned.
  2. Check broker version consistency across masters; align all brokers to one RocketMQ release.
  3. Ensure the address being queried is a native broker, not a 5.x proxy with a different response format.
  4. Extend repairConsumerStatusJSON/convertObjectKeyedInt64Map to handle the new body shape, or upgrade the driver.
  5. Retry: a transient truncation will usually succeed on a second request.
Defensive patterns

Strategy: try-catch

Validate before calling

// sanity-check the broker returns JSON before relying on status decoding
var probe map[string]json.RawMessage
if err := json.Unmarshal(body, &probe); err != nil {
    return fmt.Errorf("broker returned non-JSON body (%d bytes): %w", len(body), err)
}
if _, ok := probe["consumerTable"]; !ok {
    log.Printf("warning: response lacks consumerTable key; keys=%v", keys(probe))
}

Type guard

func isDecodeError(err error) bool {
    return err != nil && strings.Contains(err.Error(), "decode consumer status:")
}

Try / catch

status, err := agent.GetConsumeStatus(ctx, topic, group, "")
if err != nil && isDecodeError(err) {
    log.Printf("undecodable broker body for %s: %v — dumping raw response", group, err)
    dumpBrokerResponse(topic, group)
    return fallbackStatusFromClientConnections(ctx, group)
}

Prevention

When it happens

Trigger: Calling GetConsumeStatus / readConsumerStatusFromBrokers when a broker returns a body that, even after repairRocketMQJSON and convertObjectKeyedInt64Map processing, is not valid JSON or does not match {"consumerTable": map[string]map[string]int64} — e.g. truncated response, HTML error page, or unexpected field types.

Common situations: Mixed RocketMQ broker versions emitting different response shapes; proxy/load balancer returning an error page instead of JSON; response body truncated by network issues; a RocketMQ version whose JSON shape defeats the repair heuristics; running against a proxy (e.g. RocketMQ 5.x proxy) instead of a native broker.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/518fe7eec888ec4c. Report an issue: GitHub.